void TMregion_free (TM_ARGDECL region_t* regionPtr) { PVECTOR_FREE(regionPtr->badVectorPtr); TMLIST_FREE(regionPtr->borderListPtr); TMLIST_FREE(regionPtr->beforeListPtr); TMQUEUE_FREE(regionPtr->expandQueuePtr); TM_FREE(regionPtr); }
/* ============================================================================= * Pregion_free * ============================================================================= */ void Pregion_free (region_t* regionPtr) { PVECTOR_FREE(regionPtr->badVectorPtr); PLIST_FREE(regionPtr->borderListPtr); PLIST_FREE(regionPtr->beforeListPtr); PQUEUE_FREE(regionPtr->expandQueuePtr); P_FREE(regionPtr); }
/* ============================================================================= * PdoTraceback * ============================================================================= */ static vector_t* PdoTraceback (grid_t* gridPtr, grid_t* myGridPtr, coordinate_t* dstPtr, long bendCost) { vector_t* pointVectorPtr = PVECTOR_ALLOC(1); assert(pointVectorPtr); point_t next; next.x = dstPtr->x; next.y = dstPtr->y; next.z = dstPtr->z; next.value = grid_getPoint(myGridPtr, next.x, next.y, next.z); next.momentum = MOMENTUM_ZERO; while (1) { long* gridPointPtr = grid_getPointRef(gridPtr, next.x, next.y, next.z); PVECTOR_PUSHBACK(pointVectorPtr, (void*)gridPointPtr); grid_setPoint(myGridPtr, next.x, next.y, next.z, GRID_POINT_FULL); /* Check if we are done */ if (next.value == 0) { break; } point_t curr = next; /* * Check 6 neighbors * * Potential Optimization: Only need to check 5 of these */ traceToNeighbor(myGridPtr, &curr, &MOVE_POSX, TRUE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_POSY, TRUE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_POSZ, TRUE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_NEGX, TRUE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_NEGY, TRUE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_NEGZ, TRUE, bendCost, &next); #if DEBUG printf("(%li, %li, %li)\n", next.x, next.y, next.z); #endif /* DEBUG */ /* * Because of bend costs, none of the neighbors may appear to be closer. * In this case, pick a neighbor while ignoring momentum. */ if ((curr.x == next.x) && (curr.y == next.y) && (curr.z == next.z)) { next.value = curr.value; traceToNeighbor(myGridPtr, &curr, &MOVE_POSX, FALSE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_POSY, FALSE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_POSZ, FALSE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_NEGX, FALSE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_NEGY, FALSE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_NEGZ, FALSE, bendCost, &next); if ((curr.x == next.x) && (curr.y == next.y) && (curr.z == next.z)) { PVECTOR_FREE(pointVectorPtr); #if DEBUG puts("[dead]"); #endif return NULL; /* cannot find path */ } } } #if DEBUG puts(""); #endif /* DEBUG */ return pointVectorPtr; }
/* ============================================================================= * getCount * ============================================================================= */ static long getCount (adtree_node_t* nodePtr, long i, long q, vector_t* queryVectorPtr, long lastQueryIndex, adtree_t* adtreePtr) { if (nodePtr == NULL) { return 0; } long nodeIndex = nodePtr->index; if (nodeIndex >= lastQueryIndex) { return nodePtr->count; } long count = 0L; query_t* queryPtr = (query_t*)vector_at(queryVectorPtr, q); if (!queryPtr) { return nodePtr->count; } long queryIndex = queryPtr->index; assert(queryIndex <= lastQueryIndex); vector_t* varyVectorPtr = nodePtr->varyVectorPtr; adtree_vary_t* varyPtr = (adtree_vary_t*)vector_at(varyVectorPtr, (queryIndex - nodeIndex - 1)); assert(varyPtr); long queryValue = queryPtr->value; if (queryValue == varyPtr->mostCommonValue) { /* * We do not explicitly store the counts for the most common value. * We can calculate it by finding the count of the query without * the current (superCount) and subtracting the count for the * query with the current toggled (invertCount). */ long numQuery = vector_getSize(queryVectorPtr); vector_t* superQueryVectorPtr = PVECTOR_ALLOC(numQuery - 1); assert(superQueryVectorPtr); long qq; for (qq = 0; qq < numQuery; qq++) { if (qq != q) { bool_t status = vector_pushBack(superQueryVectorPtr, vector_at(queryVectorPtr, qq)); assert(status); } } long superCount = adtree_getCount(adtreePtr, superQueryVectorPtr); PVECTOR_FREE(superQueryVectorPtr); long invertCount; if (queryValue == 0) { queryPtr->value = 1; invertCount = getCount(nodePtr, i, q, queryVectorPtr, lastQueryIndex, adtreePtr); queryPtr->value = 0; } else { queryPtr->value = 0; invertCount = getCount(nodePtr, i, q, queryVectorPtr, lastQueryIndex, adtreePtr); queryPtr->value = 1; } count += superCount - invertCount; } else { if (queryValue == 0) { count += getCount(varyPtr->zeroNodePtr, (i + 1), (q + 1), queryVectorPtr, lastQueryIndex, adtreePtr); } else if (queryValue == 1) { count += getCount(varyPtr->oneNodePtr, (i + 1), (q + 1), queryVectorPtr, lastQueryIndex, adtreePtr); } else { /* QUERY_VALUE_WILDCARD */ #if 0 count += getCount(varyPtr->zeroNodePtr, (i + 1), (q + 1), queryVectorPtr, lastQueryIndex, adtreePtr); count += getCount(varyPtr->oneNodePtr, (i + 1), (q + 1), queryVectorPtr, lastQueryIndex, adtreePtr); #else assert(0); /* catch bugs in learner */ #endif } } return count; }