00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "vfer_btree_delay.h"
00017 #include "vfer.h"
00018
00019
00020 static void Tree_Print_Helper (node_t* node);
00021 inline static node_t* Tree_Acquire_Node (tree_t* tree);
00022 inline static void Tree_Release_Node (tree_t* tree, node_t* node);
00023 inline static void Tree_RotateR (tree_t* tree, node_t* node);
00024 inline static void Tree_RotateL (tree_t* tree, node_t* node);
00025 inline static void Tree_Delete (tree_t* tree, node_t* node);
00026 inline static void Tree_Balance (tree_t* tree, node_t* node);
00027
00028
00029
00030
00031
00032
00033 static void Tree_Print_Helper(node_t* node) {
00034 printf("[%d](", node->val);
00035 if (node->left != NULL) {
00036 Tree_Print_Helper(node->left);
00037 }
00038 printf(")(");
00039 if (node->right != NULL) {
00040 Tree_Print_Helper(node->right);
00041 }
00042 printf(")");
00043 return;
00044 }
00045
00046
00047
00048
00049
00050
00051
00052
00053 inline static node_t* Tree_Acquire_Node(tree_t* tree) {
00054 node_t* ret;
00055
00056
00057
00058
00059
00060 ALLOC(ret, node_t*, node_t, 1);
00061 if (ret == NULL) {
00062 ERROR_PRINT("btree_delay.c", "Tree_Acquire_Node", "ERROR: Failed to alloc a btree node");
00063 return NULL;
00064 }
00065 ret->parent = ret->right = ret->left = NULL;
00066 ret->height = 1;
00067 return ret;
00068 }
00069
00070
00071
00072
00073
00074
00075
00076 inline static void Tree_Release_Node(tree_t* tree, node_t* node) {
00077
00078
00079 RELEASE(node, 1);
00080 }
00081
00082
00083
00084
00085
00086
00087
00088 inline static void Tree_RotateR(tree_t* tree, node_t* node) {
00089 node_t* left_child;
00090
00091 left_child = node->left;
00092 left_child->parent = node->parent;
00093 node->left = left_child->right;
00094 if (left_child->right != NULL) {
00095 left_child->right->parent = node;
00096 }
00097 left_child->right = node;
00098 node->parent = left_child;
00099
00100 if (left_child->parent == NULL) {
00101 tree->root = left_child;
00102 } else {
00103 if (left_child->parent->right == node) {
00104 left_child->parent->right = left_child;
00105 } else {
00106 left_child->parent->left = left_child;
00107 }
00108 }
00109 NODE_RECOMPUTE_HEIGHT(node);
00110 NODE_RECOMPUTE_HEIGHT(left_child);
00111
00112
00113
00114 return;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123 inline static void Tree_RotateL(tree_t* tree, node_t* node) {
00124 node_t* right_child;
00125
00126 right_child = node->right;
00127 right_child->parent = node->parent;
00128 node->right = right_child->left;
00129 if (right_child->left != NULL) {
00130 right_child->left->parent = node;
00131 }
00132 right_child->left = node;
00133 node->parent = right_child;
00134
00135 if (right_child->parent == NULL) {
00136 tree->root = right_child;
00137 } else {
00138 if (right_child->parent->right == node) {
00139 right_child->parent->right = right_child;
00140 } else {
00141 right_child->parent->left = right_child;
00142 }
00143 }
00144
00145 NODE_RECOMPUTE_HEIGHT(node);
00146 NODE_RECOMPUTE_HEIGHT(right_child);
00147
00148
00149
00150 return;
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160 inline static void Tree_Delete(tree_t* tree, node_t* node) {
00161
00162
00163 while (node->left != NULL || node->right != NULL) {
00164 if (node->left == NULL) {
00165 Tree_RotateL(tree, node);
00166 } else {
00167 Tree_RotateR(tree, node);
00168 }
00169 }
00170
00171
00172
00173 if (node->parent == NULL) {
00174 tree->root = NULL;
00175 } else {
00176 if (node->parent->left == node) {
00177 node->parent->left = NULL;
00178 } else {
00179 node->parent->right = NULL;
00180 }
00181 }
00182 Tree_Release_Node(tree, node);
00183
00184
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194 inline static void Tree_Balance(tree_t* tree, node_t* node) {
00195 node_t* parent;
00196
00197 while (node != NULL) {
00198 parent = node->parent;
00199
00200 if (node->left != NULL &&
00201 node->height == node->left->height) {
00202 node->height++;
00203 }
00204 if (node->right != NULL &&
00205 node->height == node->right->height) {
00206 node->height++;
00207 }
00208
00209
00210
00211 if (NODE_BALANCE(node) < -1) {
00212 Tree_RotateR(tree, node);
00213 } else if (NODE_BALANCE(node) > 1) {
00214 Tree_RotateL(tree, node);
00215 }
00216 node = parent;
00217 }
00218
00219
00220 return;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230 void Tree_Init(tree_t* tree, struct timeval window) {
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 tree->root = NULL;
00241
00242 tree->window = window;
00243 tree->last_val.val = 0;
00244 tree->last_val.stamp.tv_sec = 0;
00245 tree->last_val.stamp.tv_usec = 0;
00246
00247 }
00248
00249
00250
00251
00252
00253
00254
00255 void Tree_Set_Window(tree_t* tree, struct timeval window) {
00256 tree->window = window;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 void Tree_Insert(tree_t* tree, int32_t val, struct timeval stamp) {
00269 node_t* root;
00270 node_t* tmp;
00271
00272
00273 tree->last_val.val = val;
00274 tree->last_val.stamp = stamp;
00275
00276 root = tree->root;
00277 do {
00278 if (root == NULL) {
00279
00280
00281
00282 root = Tree_Acquire_Node(tree);
00283 if (root == NULL) {
00284
00285 return;
00286 }
00287 root->val = val;
00288 root->stamp = stamp;
00289 tree->root = root;
00290
00291
00292 return;
00293 }
00294
00295 if (val == root->val) {
00296 root->stamp = stamp;
00297
00298
00299 return;
00300 }
00301
00302
00303
00304 if (VALUE_EXPIRED(root->stamp, stamp, tree->window)) {
00305
00306
00307
00308
00309 tmp = root->parent;
00310 Tree_Delete(tree, root);
00311 if (tmp == NULL) {
00312 root = tree->root;
00313 } else {
00314 root = tmp;
00315 }
00316 continue;
00317 }
00318 if (val < root->val) {
00319 if (root->left == NULL) {
00320 goto add_left;
00321 }
00322 root = root->left;
00323 } else {
00324 if (root->right == NULL) {
00325 goto add_right;
00326 }
00327 root = root->right;
00328 }
00329 } while (1);
00330 add_left:
00331
00332 root->left = Tree_Acquire_Node(tree);
00333 if (root->left == NULL) {
00334
00335
00336 return;
00337 }
00338 root->left->val = val;
00339 root->left->stamp = stamp;
00340 root->left->parent = root;
00341
00342 if (root->right == NULL) {
00343 root->height = 2;
00344 }
00345 Tree_Balance(tree, root->parent);
00346
00347
00348 return;
00349 add_right:
00350
00351 root->right = Tree_Acquire_Node(tree);
00352 if (root->right == NULL) {
00353
00354
00355 return;
00356 }
00357 root->right->val = val;
00358 root->right->stamp = stamp;
00359 root->right->parent = root;
00360
00361 if (root->left == NULL) {
00362 root->height = 2;
00363 }
00364 Tree_Balance(tree, root->parent);
00365
00366
00367 return;
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377 int32_t Tree_Min(tree_t* tree, struct timeval stamp) {
00378 node_t* root;
00379 node_t* tmp;
00380
00381 if (tree->root == NULL) {
00382 return tree->last_val.val;
00383 }
00384
00385 root = tree->root;
00386 do {
00387
00388
00389 while (VALUE_EXPIRED(root->stamp, stamp, tree->window)) {
00390 tmp = root->parent;
00391 Tree_Delete(tree, root);
00392 if (tmp == NULL) {
00393 if (tree->root == NULL) {
00394
00395 return tree->last_val.val;
00396 }
00397 root = tree->root;
00398 } else {
00399 root = tmp;
00400 }
00401 }
00402 } while ((root->left != NULL) && (root = root->left));
00403 return root->val;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413 int32_t Tree_Max(tree_t* tree, struct timeval stamp) {
00414 node_t* root;
00415 node_t* tmp;
00416
00417 if (tree->root == NULL) {
00418 return tree->last_val.val;
00419 }
00420
00421 root = tree->root;
00422 do {
00423
00424
00425 while (VALUE_EXPIRED(root->stamp, stamp, tree->window)) {
00426 tmp = root->parent;
00427 Tree_Delete(tree, root);
00428 if (tmp == NULL) {
00429 if (tree->root == NULL) {
00430
00431 return tree->last_val.val;
00432 }
00433 root = tree->root;
00434 } else {
00435 root = tmp;
00436 }
00437 }
00438 } while ((root->right != NULL) && (root = root->right));
00439 return root->val;
00440 }
00441
00442
00443
00444
00445
00446
00447 void Tree_Print(tree_t* tree) {
00448 if (tree->root != NULL) {
00449 Tree_Print_Helper(tree->root);
00450 printf("\n");
00451 } else {
00452 printf("Empty Tree\n");
00453 }
00454 }