Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

_timer_heapify.c

Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 2005 by Kevin L. Mitchell <klmitch@mit.edu>
00003 **
00004 ** This program is free software; you can redistribute it and/or modify
00005 ** it under the terms of the GNU General Public License as published by
00006 ** the Free Software Foundation; either version 2 of the License, or
00007 ** (at your option) any later version.
00008 **
00009 ** This program is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 ** GNU General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU General Public License
00015 ** along with this program; if not, write to the Free Software
00016 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 **
00018 ** @(#)$Id: _timer_heapify.c,v 1.7 2005/12/18 00:15:10 klmitch Exp $
00019 */
00029 #include "event_int.h"
00030 
00031 RCSTAG("@(#)$Id: _timer_heapify.c,v 1.7 2005/12/18 00:15:10 klmitch Exp $");
00032 
00046 static ev_err_t
00047 node_swap(ev_ctx_t *ctx, ev_tim_t *tim)
00048 {
00049   ev_tim_t *parent = tim->ti_node.tn_parent;
00050   _ev_timnode_t swap;
00051 
00052   ev_trace();
00053 
00054   /* First, let's swap the node pointer values */
00055   swap = parent->ti_node;
00056   parent->ti_node = tim->ti_node;
00057   tim->ti_node = swap;
00058 
00059   /* one or the other of these must be true... */
00060   ev_assert(tim->ti_node.tn_left == tim || tim->ti_node.tn_right == tim);
00061 
00062   /* Fix up the timer for its new position... */
00063   if (tim->ti_node.tn_left == tim)
00064     tim->ti_node.tn_left = parent;
00065   else
00066     tim->ti_node.tn_right = parent;
00067 
00068   /* make sure parent was linked... */
00069   ev_assert((!tim->ti_node.tn_parent && ctx->ec_timtree.tt_root == parent) ||
00070             tim->ti_node.tn_parent->ti_node.tn_left == parent ||
00071             tim->ti_node.tn_parent->ti_node.tn_right == parent);
00072 
00073   /* fix up timer's parent for the new position */
00074   if (!tim->ti_node.tn_parent) /* no parent, must be the root of the tree */
00075     ctx->ec_timtree.tt_root = tim;
00076   else if (tim->ti_node.tn_parent->ti_node.tn_left == parent)
00077     tim->ti_node.tn_parent->ti_node.tn_left = tim;
00078   else
00079     tim->ti_node.tn_parent->ti_node.tn_right = tim;
00080 
00081   /* Now fix up the linked list... */
00082   if (tim->ti_node.tn_next == tim)
00083     tim->ti_node.tn_next = parent;
00084   if (tim->ti_node.tn_prev == tim)
00085     tim->ti_node.tn_prev = parent;
00086   if (parent->ti_node.tn_next == parent)
00087     parent->ti_node.tn_next = tim;
00088   if (parent->ti_node.tn_prev == parent)
00089     parent->ti_node.tn_prev = tim;
00090 
00091   /* make sure everyone else is pointing at the right place... */
00092   tt_node_fix(parent);
00093   tt_node_fix(tim);
00094 
00095   /* finally, update the insertion cursor */
00096   if (ctx->ec_timtree.tt_insert == parent)
00097     ctx->ec_timtree.tt_insert = tim;
00098   else if (ctx->ec_timtree.tt_insert == tim)
00099     ctx->ec_timtree.tt_insert = parent;
00100 
00101   ev_return(0);
00102 }
00103 
00104 ev_err_t
00105 _timer_heapify_up(ev_ctx_t *ctx, ev_tim_t *tim)
00106 {
00107   ev_err_t err;
00108 
00109   ev_trace();
00110 
00111   /* bubble earlier timeouts upwards */
00112   while (tim->ti_node.tn_parent &&
00113          tv_comp(&tim->ti_expire, &tim->ti_node.tn_parent->ti_expire) < 0)
00114     if ((err = node_swap(ctx, tim)))
00115       ev_return(err); /* handle any assertion failures that cropped up */
00116 
00117   ev_return(0);
00118 }
00119 
00120 ev_err_t
00121 _timer_heapify_down(ev_ctx_t *ctx, ev_tim_t *tim)
00122 {
00123   ev_err_t err = 0;
00124   int left, right;
00125 
00126   ev_trace();
00127 
00128   /* bubble later timeouts downwards */
00129   while (1) { /* first, calculate the delta with the children */
00130     left  = (!tim->ti_node.tn_left  ? 0 :
00131              tv_comp(&tim->ti_expire, &tim->ti_node.tn_left->ti_expire));
00132     right = (!tim->ti_node.tn_right ? 0 :
00133              tv_comp(&tim->ti_expire, &tim->ti_node.tn_right->ti_expire));
00134 
00135     if (left <= 0 && right <= 0) /* in order?  stop heapifying... */
00136       break;
00137 
00138     if (left > right) /* check which node to swap with... */
00139       err = node_swap(ctx, tim->ti_node.tn_left);
00140     else
00141       err = node_swap(ctx, tim->ti_node.tn_right);
00142 
00143     if (err) /* handle any assertion failures that cropped up */
00144       ev_return(err);
00145   }
00146 
00147   ev_return(0);
00148 }

Generated on Wed Dec 28 23:36:56 2005 for event by  doxygen 1.4.4