/* ============================================================================= * addReservation * -- If 'num' > 0 then add, if < 0 remove * -- Adding 0 seats is error if does not exist * -- If 'price' < 0, do not update price * -- Returns true on success, else false * ============================================================================= */ bool addReservation (TM_ARGDECL MAP_T* tablePtr, long id, long num, long price) { reservation_t* reservationPtr; reservationPtr = (reservation_t*)TMMAP_FIND(tablePtr, id); if (reservationPtr == NULL) { /* Create new reservation */ if (num < 1 || price < 0) { return false; } reservationPtr = RESERVATION_ALLOC(id, num, price); assert(reservationPtr != NULL); TMMAP_INSERT(tablePtr, id, reservationPtr); } else { /* Update existing reservation */ if (!RESERVATION_ADD_TO_TOTAL(reservationPtr, num)) { return false; } if ((long)TM_SHARED_READ_L(reservationPtr->numTotal) == 0) { bool status = TMMAP_REMOVE(tablePtr, id); if (!status) { TM_RESTART(); } RESERVATION_FREE(reservationPtr); } else { RESERVATION_UPDATE_PRICE(reservationPtr, price); } } return true; }
/* ============================================================================= * cancel * -- Customer is not allowed to cancel multiple times * -- Returns true on success, else false * ============================================================================= */ static TM_CALLABLE bool cancel (TM_ARGDECL MAP_T* tablePtr, MAP_T* customerTablePtr, long customerId, long id, reservation_type_t type) { customer_t* customerPtr; reservation_t* reservationPtr; customerPtr = (customer_t*)TMMAP_FIND(customerTablePtr, customerId); if (customerPtr == NULL) { return false; } reservationPtr = (reservation_t*)TMMAP_FIND(tablePtr, id); if (reservationPtr == NULL) { return false; } if (!RESERVATION_CANCEL(reservationPtr)) { return false; } if (!CUSTOMER_REMOVE_RESERVATION_INFO(customerPtr, type, id)) { /* Undo previous successful cancellation */ bool status = RESERVATION_MAKE(reservationPtr); if (!status) { TM_RESTART(); } return false; } return true; }
/* ============================================================================= * customer_removeReservationInfo * -- Returns TRUE if success, else FALSE * ============================================================================= */ bool_t customer_removeReservationInfo (TM_ARGDECL customer_t* customerPtr, reservation_type_t type, long id) { reservation_info_t findReservationInfo; findReservationInfo.type = type; findReservationInfo.id = id; /* price not used to compare reservation infos */ list_t* reservationInfoListPtr = (list_t*)TM_SHARED_READ_P(customerPtr->reservationInfoListPtr); reservation_info_t* reservationInfoPtr = (reservation_info_t*)TMLIST_FIND(reservationInfoListPtr, &findReservationInfo); if (reservationInfoPtr == NULL) { return FALSE; } bool_t status = TMLIST_REMOVE(reservationInfoListPtr, (void*)&findReservationInfo); if (status == FALSE) { TM_RESTART(); } RESERVATION_INFO_FREE(reservationInfoPtr); return TRUE; }
/* ============================================================================= * manager_deleteCustomer * -- Delete this customer and associated reservations * -- If customer does not exist, returns success * -- Returns true on success, else false * ============================================================================= */ bool manager_deleteCustomer (TM_ARGDECL manager_t* managerPtr, long customerId) { customer_t* customerPtr; MAP_T* reservationTables[NUM_RESERVATION_TYPE]; list_t* reservationInfoListPtr; list_iter_t it; bool status; customerPtr = (customer_t*)TMMAP_FIND(managerPtr->customerTablePtr, customerId); if (customerPtr == NULL) { return false; } reservationTables[RESERVATION_CAR] = managerPtr->carTablePtr; reservationTables[RESERVATION_ROOM] = managerPtr->roomTablePtr; reservationTables[RESERVATION_FLIGHT] = managerPtr->flightTablePtr; /* Cancel this customer's reservations */ reservationInfoListPtr = customerPtr->reservationInfoListPtr; TMLIST_ITER_RESET(&it, reservationInfoListPtr); while (TMLIST_ITER_HASNEXT(&it, reservationInfoListPtr)) { reservation_info_t* reservationInfoPtr; reservation_t* reservationPtr; reservationInfoPtr = (reservation_info_t*)TMLIST_ITER_NEXT(&it, reservationInfoListPtr); reservationPtr = (reservation_t*)TMMAP_FIND(reservationTables[reservationInfoPtr->type], reservationInfoPtr->id); if (reservationPtr == NULL) { TM_RESTART(); } status = RESERVATION_CANCEL(reservationPtr); if (!status) { TM_RESTART(); } RESERVATION_INFO_FREE(reservationInfoPtr); } status = TMMAP_REMOVE(managerPtr->customerTablePtr, customerId); if (!status) { TM_RESTART(); } CUSTOMER_FREE(customerPtr); return true; }
/* ============================================================================= * checkReservation * -- Check if consistent * ============================================================================= */ static void checkReservation (TM_ARGDECL reservation_t* reservationPtr) { int numUsed = (int)TM_SHARED_READ(reservationPtr->numUsed); if (numUsed < 0) { TM_RESTART(); } int numFree = (int)TM_SHARED_READ(reservationPtr->numFree); if (numFree < 0) { TM_RESTART(); } int numTotal = (int)TM_SHARED_READ(reservationPtr->numTotal); if (numTotal < 0) { TM_RESTART(); } if ((numUsed + numFree) != numTotal) { TM_RESTART(); } }
/* ============================================================================= * TMgrid_addPath * ============================================================================= */ void TMgrid_addPath (TM_ARGDECL grid_t* gridPtr, vector_t* pointVectorPtr) { long i; long n = vector_getSize(pointVectorPtr); for (i = 1; i < (n-1); i++) { long* gridPointPtr = (long*)vector_at(pointVectorPtr, i); long value = (long)TM_SHARED_READ_L(*gridPointPtr); if (value != GRID_POINT_EMPTY) { TM_RESTART(); } TM_SHARED_WRITE_L(*gridPointPtr, (long)GRID_POINT_FULL); } }
/* ============================================================================= * manager_addCustomer * -- If customer already exists, returns failure * -- Returns true on success, else false * ============================================================================= */ bool manager_addCustomer (TM_ARGDECL manager_t* managerPtr, long customerId) { customer_t* customerPtr; bool status; if (TMMAP_CONTAINS(managerPtr->customerTablePtr, customerId)) { return false; } customerPtr = CUSTOMER_ALLOC(customerId); assert(customerPtr != NULL); status = TMMAP_INSERT(managerPtr->customerTablePtr, customerId, customerPtr); if (!status) { TM_RESTART(); } return true; }
/* ============================================================================= * manager_addCustomer * -- If customer already exists, returns failure * -- Returns TRUE on success, else FALSE * ============================================================================= */ bool_t manager_addCustomer (TM_ARGDECL manager_t* managerPtr, long customerId) { customer_t* customerPtr; bool_t status; if (TMMAP_CONTAINS(managerPtr->customerTablePtr, customerId)) { return FALSE; } customerPtr = CUSTOMER_ALLOC(customerId); assert(customerPtr != NULL); status = TMMAP_INSERT(managerPtr->customerTablePtr, customerId, customerPtr); if (status == FALSE) { TM_RESTART(); } return TRUE; }
/* ============================================================================= * reserve * -- Customer is not allowed to reserve same (type, id) multiple times * -- Returns true on success, else false * ============================================================================= */ static bool reserve (TM_ARGDECL MAP_T* tablePtr, MAP_T* customerTablePtr, long customerId, long id, reservation_type_t type) { customer_t* customerPtr; reservation_t* reservationPtr; customerPtr = (customer_t*)TMMAP_FIND(customerTablePtr, customerId); if (customerPtr == NULL) { return false; } reservationPtr = (reservation_t*)TMMAP_FIND(tablePtr, id); if (reservationPtr == NULL) { return false; } if (!RESERVATION_MAKE(reservationPtr)) { return false; } if (!CUSTOMER_ADD_RESERVATION_INFO( customerPtr, type, id, (long)TM_SHARED_READ_L(reservationPtr->price))) { /* Undo previous successful reservation */ bool status = RESERVATION_CANCEL(reservationPtr); if (!status) { TM_RESTART(); } return false; } return true; }
/* ============================================================================= * TMgrowRegion * -- Return NULL if success, else pointer to encroached boundary * ============================================================================= */ element_t* TMgrowRegion (TM_ARGDECL element_t* centerElementPtr, region_t* regionPtr, mesh_t* meshPtr, MAP_T* edgeMapPtr) { bool_t isBoundary = FALSE; if (element_getNumEdge(centerElementPtr) == 1) { isBoundary = TRUE; } list_t* beforeListPtr = regionPtr->beforeListPtr; list_t* borderListPtr = regionPtr->borderListPtr; queue_t* expandQueuePtr = regionPtr->expandQueuePtr; PLIST_CLEAR(beforeListPtr); PLIST_CLEAR(borderListPtr); PQUEUE_CLEAR(expandQueuePtr); coordinate_t centerCoordinate = TMelement_getNewPoint(TM_ARG centerElementPtr); coordinate_t* centerCoordinatePtr = ¢erCoordinate; PQUEUE_PUSH(expandQueuePtr, (void*)centerElementPtr); while (!PQUEUE_ISEMPTY(expandQueuePtr)) { element_t* currentElementPtr = (element_t*)PQUEUE_POP(expandQueuePtr); PLIST_INSERT(beforeListPtr, (void*)currentElementPtr); /* no duplicates */ list_t* neighborListPtr = TMelement_getNeighborListPtr(TM_ARG currentElementPtr); list_iter_t it; TMLIST_ITER_RESET(&it, neighborListPtr); while (TMLIST_ITER_HASNEXT(&it, neighborListPtr)) { element_t* neighborElementPtr = (element_t*)TMLIST_ITER_NEXT(&it, neighborListPtr); TMELEMENT_ISGARBAGE(neighborElementPtr); /* so we can detect conflicts */ if (!list_find(beforeListPtr, (void*)neighborElementPtr)) { if (element_isInCircumCircle(neighborElementPtr, centerCoordinatePtr)) { /* This is part of the region */ if (!isBoundary && (element_getNumEdge(neighborElementPtr) == 1)) { /* Encroached on mesh boundary so split it and restart */ return neighborElementPtr; } else { /* Continue breadth-first search */ bool_t isSuccess; isSuccess = PQUEUE_PUSH(expandQueuePtr, (void*)neighborElementPtr); assert(isSuccess); } } else { /* This element borders region; save info for retriangulation */ edge_t* borderEdgePtr = TMelement_getCommonEdge(TM_ARG neighborElementPtr, currentElementPtr); if (!borderEdgePtr) { TM_RESTART(); } PLIST_INSERT(borderListPtr, (void*)borderEdgePtr); /* no duplicates */ if (!MAP_CONTAINS(edgeMapPtr, borderEdgePtr)) { PMAP_INSERT(edgeMapPtr, borderEdgePtr, neighborElementPtr); } } } /* not visited before */ } /* for each neighbor */ } /* breadth-first search */ return NULL; }