taskrambler  0.1.9
Web server and task management solution.
memory.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <search.h>
#include <unistd.h>
#include "utils/memory.h"
#include "tree.h"
+ Include dependency graph for memory.c:

Go to the source code of this file.

Data Structures

struct  memSegment
 

Macros

#define _GNU_SOURCE
 

Functions

struct memSegmentnewElement (size_t size)
 
struct memSegmentfindElement (struct memSegment *tree, size_t size)
 
struct memSegmentgrandparent (struct memSegment *node)
 
struct memSegmentuncle (struct memSegment *node)
 
struct memSegmentsibling (struct memSegment *node)
 
void rotateLeft (struct memSegment **tree, struct memSegment *node)
 
void rotateRight (struct memSegment **tree, struct memSegment *node)
 
void replaceNode (struct memSegment **tree, struct memSegment *node1, struct memSegment *node2)
 
struct memSegmentinsertElement (struct memSegment **tree, struct memSegment *element)
 
struct memSegmentfindInOrderSuccessor (struct memSegment *tree)
 
struct memSegmentdeleteElement (struct memSegment **tree, struct memSegment *element)
 
void traverse (struct memSegment *tree, void(*cb)(struct memSegment *, int))
 
void post (struct memSegment *tree, void(*cb)(struct memSegment *, int))
 
void printElement (struct memSegment *node, int depth)
 
void cleanup (struct memSegment *node, int depth)
 
static void segmentFree (struct memSegment *segment, int depth)
 
void * memNewRef (void *mem)
 
void * memMalloc (size_t size)
 
void * memCalloc (size_t nmemb, size_t size)
 
void memFree (void **mem)
 
size_t memGetSize (void *mem)
 
void memCleanup ()
 

Variables

struct memSegmentsegments = NULL
 

Data Structure Documentation

struct memSegment

Definition at line 60 of file memory.c.

+ Collaboration diagram for memSegment:
Data Fields
enum rbColor color
struct memSegment * last
struct memSegment * left
struct memSegment * next
struct memSegment * parent
void * ptr
size_t ref_count
struct memSegment * right
size_t size

Macro Definition Documentation

#define _GNU_SOURCE

Definition at line 47 of file memory.c.

Function Documentation

void cleanup ( struct memSegment node,
int  depth 
)

Definition at line 747 of file memory.c.

References memSegment::next.

748 {
749  while (NULL != node) {
750  struct memSegment * next = node->next;
751  free(node);
752  node = next;
753  }
754 }
struct memSegment * next
Definition: memory.c:68
struct memSegment* deleteElement ( struct memSegment **  tree,
struct memSegment element 
)

Definition at line 389 of file memory.c.

References memSegment::color, findInOrderSuccessor(), memSegment::last, memSegment::left, memSegment::next, memSegment::parent, rbBlack, rbRed, replaceNode(), memSegment::right, rotateLeft(), rotateRight(), sibling(), and memSegment::size.

Referenced by memMalloc().

390 {
391  struct memSegment * node = *tree;
392  struct memSegment * del_node;
393  struct memSegment * child;
394  struct memSegment * s;
395 
396  // find the relevant node and it's parent
397  while (NULL != node) {
398 
399  if (element->size < node->size) {
400  node = node->left;
401  } else if (element->size > node->size) {
402  node = node->right;
403  } else {
404  if (NULL != node->next) {
405  if (NULL != node->parent) {
406  if (node == node->parent->left) {
407  node->parent->left = node->next;
408  } else {
409  node->parent->right = node->next;
410  }
411  } else {
412  *tree = node->next;
413  }
414 
415  if (NULL != node->left) {
416  node->left->parent = node->next;
417  }
418 
419  if (NULL != node->right) {
420  node->right->parent = node->next;
421  }
422 
423  node->next->last = node->last;
424  node->next->color = node->color;
425  node->next->parent = node->parent;
426  node->next->left = node->left;
427  node->next->right = node->right;
428 
429  return node;
430  }
431  break;
432  }
433  }
434 
435  // element not found
436  if (NULL == node) {
437  return node;
438  }
439 
440  del_node = node;
441 
442  // now our cases follows...the first one is the same as with
443  // simple binary search trees. Two non null children.
444 
445  // case 1: two children
446  if (NULL != node->left && NULL != node->right) {
447  struct memSegment * successor = findInOrderSuccessor(node);
448 
449  enum rbColor tmpcolor = successor->color;
450  struct memSegment * tmpparent = successor->parent;
451  struct memSegment * tmpleft = successor->left;
452  struct memSegment * tmpright = successor->right;
453 
454  replaceNode(tree, node, successor);
455 
456  successor->color = node->color;
457  successor->left = node->left;
458  successor->left->parent = successor;
459  // the right one might be successor...
460  if (node->right == successor) {
461  successor->right = node;
462  node->parent = successor;
463  } else {
464  successor->right = node->right;
465  node->right->parent = successor;
466  node->parent = tmpparent;
467  tmpparent->left = node;
468  }
469 
470  node->color = tmpcolor;
471  node->left = tmpleft;
472  node->right = tmpright;
473  }
474 
475  // Precondition: n has at most one non-null child.
476  child = (NULL == node->right) ? node->left : node->right;
477  replaceNode(tree, node, child);
478 
479  // delete one child case
480  // TODO this is overly complex as simply derived from the function...
481  // maybe this can be simplified. Maybe not...check.
482  if (node->color == rbBlack) {
483  if (NULL != child && child->color == rbRed) {
484  child->color = rbBlack;
485  // done despite modifying tree itself if neccessary..
486  return del_node;
487  } else {
488  if (NULL != child) {
489  node = child;
490  } else {
491  node->color = rbBlack;
492  node->left = NULL;
493  node->right = NULL;
494  }
495  }
496  } else {
497  return del_node;
498  }
499 
500  // delete and rb rebalance...
501  while(1) {
502  // case 1
503  if (NULL == node->parent) {
504  // done again
505  break;
506  }
507 
508  // case 2
509  s = sibling(node);
510 
511  if (NULL != s && s->color == rbRed) {
512  node->parent->color = rbRed;
513  s->color = rbBlack;
514 
515  /*
516  * detect which child we are...assumption
517  * if we are not parent->right and parent->right is not
518  * null we must be left, even if its set to NULL previously
519  */
520  if (NULL != node->parent->right && node != node->parent->right) {
521  rotateLeft(tree, node->parent);
522  } else {
523  rotateRight(tree, node->parent);
524  }
525  }
526 
527  s = sibling(node);
528  // case 3 / 4
529  if (NULL == s || ((s->color == rbBlack) &&
530  (NULL == s->left || s->left->color == rbBlack) &&
531  (NULL == s->right || s->right->color == rbBlack))) {
532 
533  if (NULL != s) {
534  s->color = rbRed;
535  }
536 
537  if (node->parent->color == rbBlack) {
538  // case 3
539  node = node->parent;
540  continue;
541  } else {
542  // case 4
543  node->parent->color = rbBlack;
544  // and done again...
545  break;
546  }
547  }
548 
549  // case 5
550  if (NULL != s && s->color == rbBlack) {
551  // this if statement is trivial,
552  // due to case 2 (even though case 2 changed the sibling to a
553  // sibling's child,
554  // the sibling's child can't be red, since no red parent can
555  // have a red child).
556  //
557  // the following statements just force the red to be on the
558  // left of the left of the parent,
559  // or right of the right, so case 6 will rotate correctly.
560  if ((node == node->parent->left) &&
561  (NULL == s->right || s->right->color == rbBlack) &&
562  (NULL != s->left && s->left->color == rbRed)) {
563 
564  // this last test is trivial too due to cases 2-4.
565  s->color = rbRed;
566  s->left->color = rbBlack;
567 
568  rotateRight(tree, s);
569  } else if ((node == node->parent->right) &&
570  (NULL == s->left || s->left->color == rbBlack) &&
571  (NULL != s->right && s->right->color == rbRed)) {
572  // this last test is trivial too due to cases 2-4.
573  s->color = rbRed;
574  s->right->color = rbBlack;
575 
576  rotateLeft(tree, s);
577  }
578  }
579 
580  s = sibling(node);
581  // case 6
582  if (NULL != s) {
583  s->color = node->parent->color;
584  }
585 
586  if (NULL != node && NULL != node->parent) {
587  node->parent->color = rbBlack;
588 
589  /*
590  * detect which child we are...assumption
591  * if we are not parent->right and parent->right is not
592  * null we must be left, even if its set to NULL previously
593  */
594  if (NULL != node->parent->right && node != node->parent->right) {
595  if (NULL != s->right) {
596  s->right->color = rbBlack;
597  }
598  rotateLeft(tree, node->parent);
599  } else {
600  if (NULL != s->left) {
601  s->left->color = rbBlack;
602  }
603  rotateRight(tree, node->parent);
604  }
605  }
606 
607  // done...
608  break;
609  }
610 
611  return del_node;
612 }
struct memSegment * sibling(struct memSegment *node)
Definition: memory.c:152
struct memSegment * left
Definition: memory.c:72
struct memSegment * findInOrderSuccessor(struct memSegment *tree)
Definition: memory.c:377
void replaceNode(struct memSegment **tree, struct memSegment *node1, struct memSegment *node2)
Definition: memory.c:221
struct memSegment * last
Definition: memory.c:69
rbColor
Definition: tree.h:115
void rotateRight(struct memSegment **tree, struct memSegment *node)
Definition: memory.c:195
size_t size
Definition: memory.c:63
struct memSegment * parent
Definition: memory.c:71
Definition: tree.h:115
enum rbColor color
Definition: memory.c:66
struct memSegment * next
Definition: memory.c:68
void rotateLeft(struct memSegment **tree, struct memSegment *node)
Definition: memory.c:169
struct memSegment * right
Definition: memory.c:73
Definition: tree.h:115

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

struct memSegment* findElement ( struct memSegment tree,
size_t  size 
)

find element in tree

Definition at line 100 of file memory.c.

References memSegment::left, memSegment::right, and memSegment::size.

Referenced by memMalloc().

101 {
102  struct memSegment * fitting = NULL;
103 
104  while (NULL != tree) {
105  if (tree->size == size) {
106  fitting = tree;
107  break;
108  }
109 
110  if (size > tree->size) {
111  tree = tree->right;
112  } else {
113  fitting = tree;
114  tree = tree->left;
115  }
116  }
117 
118  return fitting;
119 }
struct memSegment * left
Definition: memory.c:72
static size_t size
size_t size
Definition: memory.c:63
struct memSegment * right
Definition: memory.c:73

+ Here is the caller graph for this function:

struct memSegment* findInOrderSuccessor ( struct memSegment tree)

delete element from tree

here multiple functions are involved....

find minimum of the right subtree aka leftmost leaf of right subtree aka left in-order successor. We return the parent of the element in the out argument parent. This can be NULL wenn calling.

2: *successor = {size = 80, ptr = 0x603ae0, color = rbRed, parent = 0x603160, left = 0x0, right = 0x0} 1: *node = {size = 70, ptr = 0x603a60, color = rbBlack, parent = 0x603070, left = 0x6030e0, right = 0x6031e0}

Definition at line 377 of file memory.c.

References memSegment::left, and memSegment::right.

Referenced by deleteElement().

378 {
379  struct memSegment * node = tree->right;
380 
381  while (NULL != node->left) {
382  node = node->left;
383  }
384 
385  return node;
386 }
struct memSegment * left
Definition: memory.c:72
struct memSegment * right
Definition: memory.c:73

+ Here is the caller graph for this function:

struct memSegment* grandparent ( struct memSegment node)

Definition at line 126 of file memory.c.

References memSegment::parent.

Referenced by insertElement(), and uncle().

127 {
128  if (NULL != node && NULL != node->parent) {
129  return node->parent->parent;
130  }
131 
132  return NULL;
133 }
struct memSegment * parent
Definition: memory.c:71

+ Here is the caller graph for this function:

struct memSegment* insertElement ( struct memSegment **  tree,
struct memSegment element 
)

insert element in tree

Definition at line 246 of file memory.c.

References memSegment::color, grandparent(), memSegment::last, memSegment::left, memSegment::next, memSegment::parent, rbBlack, rbRed, memSegment::right, rotateLeft(), rotateRight(), memSegment::size, and uncle().

Referenced by memFree().

247 {
248  struct memSegment * node = *tree;
249  struct memSegment * new_node = NULL;
250  struct memSegment * u;
251  struct memSegment * g;
252 
253  element->next = NULL;
254  element->last = NULL;
255 
256  element->color = rbRed;
257  element->parent = NULL;
258  element->left = NULL;
259  element->right = NULL;
260 
261  // if tree is empty it's simple... :)
262  if (NULL == node) {
263  *tree = node = new_node = element;
264  } else {
265  // normal binary tree add....
266  while (NULL != node) {
267  if (element->size < node->size) {
268  if (NULL == node->left) {
269  node->left = element;
270  node->left->parent = node;
271  new_node = node = node->left;
272  break;
273  } else {
274  node = node->left;
275  }
276  } else if (element->size > node->size) {
277  if (NULL == node->right) {
278  node->right = element;
279  node->right->parent = node;
280  new_node = node = node->right;
281  break;
282  } else {
283  node = node->right;
284  }
285  } else {
286  if (NULL == node->next) {
287  node->next = element;
288  node->last = element;
289  } else {
290  node->last->next = element;
291  node->last = element;
292  }
293  return node;
294  }
295  }
296  }
297 
298  if (NULL != new_node) {
299  /*
300  * handle reballancing rb style
301  */
302  while (1) {
303  // case 1
304  if (node->parent == NULL) {
305  node->color = rbBlack;
306  // we're done.... :)
307  break;
308  }
309 
310  // case 2
311  if (node->parent->color == rbBlack) {
312  // Tree is still valid ... wow, again we're done... :)
313  break;
314  }
315 
316  // case 3
317  u = uncle(node);
318  g = grandparent(node);
319 
320  if (u != NULL && u->color == rbRed) {
321  node->parent->color = rbBlack;
322  u->color = rbBlack;
323  g->color = rbRed;
324 
325  node = g;
326  continue;
327  }
328 
329  // case 4
330  if (node == node->parent->right && node->parent == g->left) {
331  rotateLeft(tree, node->parent);
332  node = node->left;
333  } else if (node == node->parent->left && node->parent == g->right) {
334 
335  rotateRight(tree, node->parent);
336  node = node->right;
337  }
338 
339  // case 5
340  g = grandparent(node);
341 
342  node->parent->color = rbBlack;
343  g->color = rbRed;
344 
345  if (node == node->parent->left) {
346  rotateRight(tree, g);
347  } else {
348  rotateLeft(tree, g);
349  }
350 
351  // we're done..
352  break;
353  }
354  }
355 
356  return new_node;
357 }
struct memSegment * uncle(struct memSegment *node)
Definition: memory.c:136
struct memSegment * left
Definition: memory.c:72
struct memSegment * last
Definition: memory.c:69
void rotateRight(struct memSegment **tree, struct memSegment *node)
Definition: memory.c:195
size_t size
Definition: memory.c:63
struct memSegment * parent
Definition: memory.c:71
Definition: tree.h:115
enum rbColor color
Definition: memory.c:66
struct memSegment * next
Definition: memory.c:68
void rotateLeft(struct memSegment **tree, struct memSegment *node)
Definition: memory.c:169
struct memSegment * grandparent(struct memSegment *node)
Definition: memory.c:126
struct memSegment * right
Definition: memory.c:73
Definition: tree.h:115

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void* memCalloc ( size_t  nmemb,
size_t  size 
)

this is a really memory wasting solution....just to be able to use calloc, which might be faster then malloc/memset solution.

Maybe this is a bad idea, as we need to memset the buffer anyway if it comes from our tree, which hopefully should be the majority of cases.

Definition at line 818 of file memory.c.

References memMalloc(), and size.

Referenced by applicationCtor(), applicationSessionCleanup(), classClone(), classNewParams(), hash_pw(), httpMessageCtor(), httpResponseCtor(), and serverCtor().

819 {
820  size_t _size = nmemb * size;
821  void * mem = memMalloc(_size);
822 
823  memset(mem, 0, _size);
824 
825  return mem;
826 }
void * memMalloc(size_t size)
Definition: memory.c:783
static size_t size

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void memCleanup ( )

Definition at line 862 of file memory.c.

References post(), and segmentFree().

Referenced by main().

863 {
864 #ifdef MEM_OPT
866 #endif
867 }
struct memSegment * segments
Definition: memory.c:756
void post(struct memSegment *tree, void(*cb)(struct memSegment *, int))
Definition: memory.c:666
static void segmentFree(struct memSegment *segment, int depth)
Definition: memory.c:760

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void memFree ( void **  mem)

Definition at line 829 of file memory.c.

References insertElement(), and memSegment::ref_count.

830 {
831  if (NULL != *mem) {
832  struct memSegment * seg = (*mem - sizeof(struct memSegment));
833 
834  if (1 < seg->ref_count) {
835  seg->ref_count--;
836  } else {
837 #ifdef MEM_OPT
838  insertElement(&segments, seg);
839 #else
840  free(seg);
841 #endif
842  }
843 
844  *mem = NULL;
845  }
846 }
struct memSegment * segments
Definition: memory.c:756
size_t ref_count
Definition: memory.c:62
struct memSegment * insertElement(struct memSegment **tree, struct memSegment *element)
Definition: memory.c:246

+ Here is the call graph for this function:

size_t memGetSize ( void *  mem)

Definition at line 849 of file memory.c.

References memSegment::size.

Referenced by httpWriterWrite().

850 {
851  struct memSegment * segment;
852 
853  if (NULL == mem) {
854  return 0;
855  }
856 
857  segment = (struct memSegment *)(mem - sizeof(struct memSegment));
858  return segment->size;
859 }
size_t size
Definition: memory.c:63

+ Here is the caller graph for this function:

void* memMalloc ( size_t  size)

Definition at line 783 of file memory.c.

References deleteElement(), findElement(), newElement(), memSegment::ptr, and size.

Referenced by authLdapCtor(), cbufCtor(), configCtor(), configValueCtor(), controllerCurrentuserRead(), controllerLocRead(), controllerRandvalRead(), controllerSessinfoRead(), controllerUserRead(), controllerVersionRead(), credentialCtor(), hashValueCtor(), httpCookieCtor(), httpHeaderCtor(), httpParserHeader(), httpParserParse(), httpParserRequestVars(), httpRequestCtor(), httpResponse404(), httpResponse500(), httpResponseJson(), httpWorkerCtor(), httpWriterWrite(), loggerLog(), memCalloc(), newEle(), storageCtor(), storageGet(), userCtor(), userSerialize(), and userUnserialize().

784 {
785  struct memSegment * seg = NULL;
786  //long psize = sysconf(_SC_PAGESIZE);
787  long psize = 64;
788 
789  size += sizeof(struct memSegment);
790 
791  /* allocate only blocks of a multiple of pagesize, similar to cbuf */
792  size = (0>=size)?1:(0!=size%psize)?(size/psize)+1:size/psize;
793  size *= psize;
794 
795 #ifdef MEM_OPT
796  seg = findElement(segments, size);
797 #endif
798 
799  if (NULL == seg) {
800  seg = newElement(size);
801  } else {
802  // remove the found one from the tree as we use it now.
803  seg = deleteElement(&segments, seg);
804  }
805 
806  return seg->ptr;
807 }
void * ptr
Definition: memory.c:64
struct memSegment * deleteElement(struct memSegment **tree, struct memSegment *element)
Definition: memory.c:389
static size_t size
struct memSegment * newElement(size_t size)
Definition: memory.c:77
struct memSegment * segments
Definition: memory.c:756
struct memSegment * findElement(struct memSegment *tree, size_t size)
Definition: memory.c:100

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void* memNewRef ( void *  mem)

Definition at line 770 of file memory.c.

References memSegment::ref_count.

771 {
772  struct memSegment * seg = (mem - sizeof(struct memSegment));
773 
774  seg->ref_count++;
775 
776  return mem;
777 }
size_t ref_count
Definition: memory.c:62
struct memSegment* newElement ( size_t  size)

Definition at line 77 of file memory.c.

References memSegment::color, memSegment::last, memSegment::left, memSegment::next, memSegment::parent, memSegment::ptr, rbRed, memSegment::ref_count, memSegment::right, size, and memSegment::size.

Referenced by memMalloc().

78 {
79  struct memSegment * element = malloc(size);
80 
81  element->ref_count = 1;
82  element->size = size;
83  element->ptr = (void*)element + sizeof(struct memSegment);
84 
85  element->next = NULL;
86  element->last = NULL;
87 
88  element->color = rbRed;
89  element->parent = NULL;
90  element->left = NULL;
91  element->right = NULL;
92 
93  return element;
94 }
struct memSegment * left
Definition: memory.c:72
void * ptr
Definition: memory.c:64
struct memSegment * last
Definition: memory.c:69
static size_t size
size_t size
Definition: memory.c:63
struct memSegment * parent
Definition: memory.c:71
size_t ref_count
Definition: memory.c:62
enum rbColor color
Definition: memory.c:66
struct memSegment * next
Definition: memory.c:68
struct memSegment * right
Definition: memory.c:73
Definition: tree.h:115

+ Here is the caller graph for this function:

void post ( struct memSegment tree,
void(*)(struct memSegment *, int)  cb 
)

Definition at line 666 of file memory.c.

References cb, memSegment::left, memSegment::parent, and memSegment::right.

Referenced by memCleanup().

667 {
668  struct memSegment * previous = tree;
669  struct memSegment * node = tree;
670  int depth = 1;
671 
672  /*
673  * I think this has something like O(n+log(n)) on a ballanced
674  * tree because I have to traverse back the rightmost leaf to
675  * the root to get a break condition.
676  */
677  while (node) {
678  /*
679  * If we come from the right so nothing and go to our
680  * next parent.
681  */
682  if (((NULL == node->left || previous == node->left)
683  && NULL == node->right)
684  || previous == node->right) {
685 
686  struct memSegment * parent = node->parent;
687 
688  cb(node, depth);
689 
690  previous = node;
691  node = parent;
692  depth--;
693  continue;
694  }
695 
696  if ((NULL == node->left || previous == node->left)) {
697  /*
698  * If there are no more elements to the left or we
699  * came from the left, process data.
700  */
701  previous = node;
702 
703  if (NULL != node->right) {
704  node = node->right;
705  depth++;
706  } else {
707  node = node->parent;
708  depth--;
709  }
710  } else {
711  /*
712  * if there are more elements to the left go there.
713  */
714  previous = node;
715  node = node->left;
716  depth++;
717  }
718  }
719 }
struct memSegment * left
Definition: memory.c:72
static void(* cb)(const void *)
Definition: each.c:27
struct memSegment * parent
Definition: memory.c:71
struct memSegment * right
Definition: memory.c:73

+ Here is the caller graph for this function:

void printElement ( struct memSegment node,
int  depth 
)

Definition at line 721 of file memory.c.

References memSegment::color, memSegment::next, memSegment::ptr, rbRed, and memSegment::size.

722 {
723  int i;
724 
725  printf("%s %010zu:%p(%02d)",
726  (node->color==rbRed)?"R":"B",
727  node->size,
728  node->ptr,
729  depth);
730  for (i=0; i<depth; i++) printf("-");
731  puts("");
732 
733  node = node->next;
734  while (NULL != node) {
735  printf(" %s %010zu:%p(%02d)",
736  (node->color==rbRed)?"R":"B",
737  node->size,
738  node->ptr,
739  depth);
740  for (i=0; i<depth; i++) printf("-");
741  puts("");
742  node = node->next;
743  }
744 }
void * ptr
Definition: memory.c:64
size_t size
Definition: memory.c:63
enum rbColor color
Definition: memory.c:66
struct memSegment * next
Definition: memory.c:68
Definition: tree.h:115
void replaceNode ( struct memSegment **  tree,
struct memSegment node1,
struct memSegment node2 
)

Definition at line 221 of file memory.c.

References memSegment::left, memSegment::parent, and memSegment::right.

Referenced by deleteElement().

225 {
226  if (NULL != node1->parent) {
227  if (node1 == node1->parent->left) {
228  node1->parent->left = node2;
229  } else {
230  node1->parent->right = node2;
231  }
232  } else {
233  *tree = node2;
234  }
235 
236  if (NULL != node2) {
237  node2->parent = node1->parent;
238  }
239 }
struct memSegment * left
Definition: memory.c:72
struct memSegment * parent
Definition: memory.c:71
struct memSegment * right
Definition: memory.c:73

+ Here is the caller graph for this function:

void rotateLeft ( struct memSegment **  tree,
struct memSegment node 
)

Definition at line 169 of file memory.c.

References memSegment::left, memSegment::parent, and memSegment::right.

Referenced by deleteElement(), and insertElement().

170 {
171  struct memSegment * rightChild = node->right;
172  struct memSegment * rcLeftSub = node->right->left;
173 
174  rightChild->left = node;
175  rightChild->parent = node->parent;
176  node->right = rcLeftSub;
177  if (NULL != rcLeftSub) {
178  rcLeftSub->parent = node;
179  }
180 
181  if (node->parent) {
182  if (node->parent->left == node) {
183  node->parent->left = rightChild;
184  } else {
185  node->parent->right = rightChild;
186  }
187  } else {
188  *tree = rightChild;
189  }
190 
191  node->parent = rightChild;
192 }
struct memSegment * left
Definition: memory.c:72
struct memSegment * parent
Definition: memory.c:71
struct memSegment * right
Definition: memory.c:73

+ Here is the caller graph for this function:

void rotateRight ( struct memSegment **  tree,
struct memSegment node 
)

Definition at line 195 of file memory.c.

References memSegment::left, memSegment::parent, and memSegment::right.

Referenced by deleteElement(), and insertElement().

196 {
197  struct memSegment * leftChild = node->left;
198  struct memSegment * lcRightSub = node->left->right;
199 
200  leftChild->right = node;
201  leftChild->parent = node->parent;
202  node->left = lcRightSub;
203  if (NULL != lcRightSub) {
204  lcRightSub->parent = node;
205  }
206 
207  if (node->parent) {
208  if (node->parent->left == node) {
209  node->parent->left = leftChild;
210  } else {
211  node->parent->right = leftChild;
212  }
213  } else {
214  *tree = leftChild;
215  }
216 
217  node->parent = leftChild;
218 }
struct memSegment * left
Definition: memory.c:72
struct memSegment * parent
Definition: memory.c:71
struct memSegment * right
Definition: memory.c:73

+ Here is the caller graph for this function:

static void segmentFree ( struct memSegment segment,
int  depth 
)
static

Definition at line 760 of file memory.c.

References memSegment::next.

Referenced by memCleanup().

761 {
762  while (NULL != segment) {
763  struct memSegment * next = segment->next;
764  free(segment);
765  segment = next;
766  }
767 }
struct memSegment * next
Definition: memory.c:68

+ Here is the caller graph for this function:

struct memSegment* sibling ( struct memSegment node)

Definition at line 152 of file memory.c.

References memSegment::left, memSegment::parent, and memSegment::right.

Referenced by deleteElement().

153 {
154  if (NULL == node) {
155  return NULL;
156  }
157 
158  if (NULL == node->parent->left || node == node->parent->left) {
159  return node->parent->right;
160  } else {
161  return node->parent->left;
162  }
163 }
struct memSegment * left
Definition: memory.c:72
struct memSegment * parent
Definition: memory.c:71
struct memSegment * right
Definition: memory.c:73

+ Here is the caller graph for this function:

void traverse ( struct memSegment tree,
void(*)(struct memSegment *, int)  cb 
)

Definition at line 616 of file memory.c.

References cb, memSegment::left, memSegment::parent, and memSegment::right.

617 {
618  struct memSegment * previous = tree;
619  struct memSegment * node = tree;
620  int depth = 1;
621 
622  /*
623  * I think this has something like O(n+log(n)) on a ballanced
624  * tree because I have to traverse back the rightmost leaf to
625  * the root to get a break condition.
626  */
627  while (node) {
628  /*
629  * If we come from the right so nothing and go to our
630  * next parent.
631  */
632  if (previous == node->right) {
633  previous = node;
634  node = node->parent;
635  depth--;
636  continue;
637  }
638 
639  if ((NULL == node->left || previous == node->left)) {
640  /*
641  * If there are no more elements to the left or we
642  * came from the left, process data.
643  */
644  cb(node, depth);
645  previous = node;
646 
647  if (NULL != node->right) {
648  node = node->right;
649  depth++;
650  } else {
651  node = node->parent;
652  depth--;
653  }
654  } else {
655  /*
656  * if there are more elements to the left go there.
657  */
658  previous = node;
659  node = node->left;
660  depth++;
661  }
662  }
663 }
struct memSegment * left
Definition: memory.c:72
static void(* cb)(const void *)
Definition: each.c:27
struct memSegment * parent
Definition: memory.c:71
struct memSegment * right
Definition: memory.c:73
struct memSegment* uncle ( struct memSegment node)

Definition at line 136 of file memory.c.

References grandparent(), memSegment::left, memSegment::parent, and memSegment::right.

Referenced by insertElement().

137 {
138  struct memSegment * gp = grandparent(node);
139 
140  if (NULL == gp) {
141  return NULL;
142  }
143 
144  if (node->parent == gp->left) {
145  return gp->right;
146  }
147 
148  return gp->left;
149 }
struct memSegment * left
Definition: memory.c:72
struct memSegment * parent
Definition: memory.c:71
struct memSegment * grandparent(struct memSegment *node)
Definition: memory.c:126
struct memSegment * right
Definition: memory.c:73

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

struct memSegment* segments = NULL

Definition at line 756 of file memory.c.