RF_DiskQueueData_t * rf_CvscanDequeue(void *q_in) { RF_CvscanHeader_t *hdr = (RF_CvscanHeader_t *) q_in; long range, i, sum_dist_left, sum_dist_right; RF_DiskQueueData_t *ret; RF_DiskQueueData_t *tmp; DO_CHECK_STATE(hdr); if (hdr->left_cnt == 0 && hdr->right_cnt == 0) return ((RF_DiskQueueData_t *) NULL); range = RF_MIN(hdr->range_for_avg, RF_MIN(hdr->left_cnt, hdr->right_cnt)); for (i = 0, tmp = hdr->left, sum_dist_left = ((hdr->direction == rf_cvscan_RIGHT) ? range * hdr->change_penalty : 0); tmp != (RF_DiskQueueData_t *) NULL && i < range; tmp = tmp->next, i++) { sum_dist_left += hdr->cur_block - tmp->sectorOffset; } for (i = 0, tmp = hdr->right, sum_dist_right = ((hdr->direction == rf_cvscan_LEFT) ? range * hdr->change_penalty : 0); tmp != (RF_DiskQueueData_t *) NULL && i < range; tmp = tmp->next, i++) { sum_dist_right += tmp->sectorOffset - hdr->cur_block; } if (hdr->right_cnt == 0 || sum_dist_left < sum_dist_right) { hdr->direction = rf_cvscan_LEFT; hdr->cur_block = hdr->left->sectorOffset + hdr->left->numSector; hdr->left_cnt = RF_MAX(hdr->left_cnt - 1, 0); tmp = hdr->left; ret = (ReqDequeue(&hdr->left)) /*->parent*/ ; } else { hdr->direction = rf_cvscan_RIGHT; hdr->cur_block = hdr->right->sectorOffset + hdr->right->numSector; hdr->right_cnt = RF_MAX(hdr->right_cnt - 1, 0); tmp = hdr->right; ret = (ReqDequeue(&hdr->right)) /*->parent*/ ; } ReBalance(hdr); if (hdr->left_cnt == 0 && hdr->right_cnt == 0 && hdr->burner != (RF_DiskQueueData_t *) NULL) { /* ** restore low priority requests for next dequeue */ RF_DiskQueueData_t *burner = hdr->burner; hdr->nxt_priority = burner->priority; while (burner != (RF_DiskQueueData_t *) NULL && burner->priority == hdr->nxt_priority) { RF_DiskQueueData_t *next = burner->next; RealEnqueue(hdr, burner); burner = next; } hdr->burner = burner; } DO_CHECK_STATE(hdr); return (ret); }
LineComparable *AvlNode::Delete(double currentSweepPointX, Inters::Line *key, AvlNode *&root, int &change, cmp_t cmp) { // See if the tree is empty if (root == NULL) { // Key not found change = HEIGHT_NOCHANGE; return NULL; } // Initialize LineComparable *found = NULL; int decrease = 0; // Compare items and determine which direction to search cmp_t result = root->Compare(key, currentSweepPointX, cmp); dir_t dir = (result == MIN_CMP) ? LEFT : RIGHT; if (result != EQ_CMP) { // Delete from "dir" subtree found = Delete(key, root->mySubtree[dir], change, cmp); if (!found) return found; // not found - can't delete decrease = result * change; // set balance factor decrement } else { // Found key at this node found = root->myData; // set return value // --------------------------------------------------------------------- // At this point we know "result" is zero and "root" points to // the node that we need to delete. There are three cases: // // 1) The node is a leaf. Remove it and return. // // 2) The node is a branch (has only 1 child). Make "root" // (the pointer to this node) point to the child. // // 3) The node has two children. We swap items with the successor // of "root" (the smallest item in its rights subtree) and delete // the successor from the rights subtree of "root". The // identifier "decrease" should be reset if the subtree height // decreased due to the deletion of the successor of "root". // --------------------------------------------------------------------- if ((root->mySubtree[LEFT] == NULL) && (root->mySubtree[RIGHT] == NULL)) { // We have a leaf -- remove it delete root; root = NULL; change = HEIGHT_CHANGE; // height changed from 1 to 0 return found; } else if ((root->mySubtree[LEFT] == NULL) || (root->mySubtree[RIGHT] == NULL)) { // We have one child -- only child becomes new root AvlNode *toDelete = root; root = root->mySubtree[(root->mySubtree[RIGHT]) ? RIGHT : LEFT]; change = HEIGHT_CHANGE; // We just shortened the subtree // Null-out the subtree pointers so we dont recursively delete toDelete->mySubtree[LEFT] = toDelete->mySubtree[RIGHT] = NULL; delete toDelete; return found; } else { // We have two children -- find successor and replace our current // data item with that of the successor root->myData = Delete(key, root->mySubtree[RIGHT], decrease, MIN_CMP); } } root->myBal -= decrease; // update balance factor // ------------------------------------------------------------------------ // Rebalance if necessary -- the height of current tree changes if one // of two things happens: (1) a rotation was performed which changed // the height of the subtree (2) the subtree height decreased and now // matches the height of its other subtree (so the current tree now // has a zero balance when it previously did not). // ------------------------------------------------------------------------ //change = (decrease) ? ((root->myBal) ? balance(root) : HEIGHT_CHANGE) // : HEIGHT_NOCHANGE ; if (decrease) { if (root->myBal) { change = ReBalance(root); // rebalance and see if height changed } else { change = HEIGHT_CHANGE; // balanced because subtree decreased } } else { change = HEIGHT_NOCHANGE; } return found; }