Advertisement
Guest User

Untitled

a guest
May 24th, 2017
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.74 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <assert.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5.  
  6. struct buddy2 {
  7.   unsigned size;
  8.   unsigned longest[1];
  9. };
  10.  
  11. #define LEFT_LEAF(index) ((index) * 2 + 1)
  12. #define RIGHT_LEAF(index) ((index) * 2 + 2)
  13. #define PARENT(index) ( ((index) + 1) / 2 - 1)
  14.  
  15. #define IS_POWER_OF_2(x) (!((x)&((x)-1)))
  16. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  17.  
  18. #define ALLOC malloc
  19. #define FREE free
  20.  
  21. static unsigned fixsize(unsigned size) {
  22.   size |= size >> 1;
  23.   size |= size >> 2;
  24.   size |= size >> 4;
  25.   size |= size >> 8;
  26.   size |= size >> 16;
  27.   return size+1;
  28. }
  29.  
  30. struct buddy2* buddy2_new( int size ) {
  31.   struct buddy2* self;
  32.   unsigned node_size;
  33.   int i;
  34.  
  35.   if (size < 1 || !IS_POWER_OF_2(size))
  36.     return NULL;
  37.  
  38.   self = (struct buddy2*)ALLOC( 2 * size * sizeof(unsigned));
  39.   self->size = size;
  40.   node_size = size * 2;
  41.  
  42.   for (i = 0; i < 2 * size - 1; ++i) {
  43.     if (IS_POWER_OF_2(i+1))
  44.       node_size /= 2;
  45.     self->longest[i] = node_size;
  46.   }
  47.   return self;
  48. }
  49.  
  50. void buddy2_destroy( struct buddy2* self) {
  51.   FREE(self);
  52. }
  53.  
  54. int buddy2_alloc(struct buddy2* self, int size) {
  55.   unsigned index = 0;
  56.   unsigned node_size;
  57.   unsigned offset = 0;
  58.  
  59.   if (self==NULL)
  60.     return -1;
  61.  
  62.   if (size <= 0)
  63.     size = 1;
  64.   else if (!IS_POWER_OF_2(size))
  65.     size = fixsize(size);
  66.  
  67.   if (self->longest[index] < size)
  68.     return -1;
  69.  
  70.   for(node_size = self->size; node_size != size; node_size /= 2 ) {
  71.     if (self->longest[LEFT_LEAF(index)] >= size)
  72.       index = LEFT_LEAF(index);
  73.     else
  74.       index = RIGHT_LEAF(index);
  75.   }
  76.  
  77.   self->longest[index] = 0;
  78.   offset = (index + 1) * node_size - self->size;
  79.  
  80.   while (index) {
  81.     index = PARENT(index);
  82.     self->longest[index] =
  83.       MAX(self->longest[LEFT_LEAF(index)], self->longest[RIGHT_LEAF(index)]);
  84.   }
  85.  
  86.   return offset;
  87. }
  88.  
  89. void buddy2_free(struct buddy2* self, int offset) {
  90.   unsigned node_size, index = 0;
  91.   unsigned left_longest, right_longest;
  92.  
  93.   assert(self && offset >= 0 && offset < self->size);
  94.  
  95.   node_size = 1;
  96.   index = offset + self->size - 1;
  97.  
  98.   for (; self->longest[index] ; index = PARENT(index)) {
  99.     node_size *= 2;
  100.     if (index == 0)
  101.       return;
  102.   }
  103.  
  104.   self->longest[index] = node_size;
  105.  
  106.   while (index) {
  107.     index = PARENT(index);
  108.     node_size *= 2;
  109.  
  110.     left_longest = self->longest[LEFT_LEAF(index)];
  111.     right_longest = self->longest[RIGHT_LEAF(index)];
  112.    
  113.     if (left_longest + right_longest == node_size)
  114.       self->longest[index] = node_size;
  115.     else
  116.       self->longest[index] = MAX(left_longest, right_longest);
  117.   }
  118. }
  119.  
  120. int buddy2_size(struct buddy2* self, int offset) {
  121.   unsigned node_size, index = 0;
  122.  
  123.   assert(self && offset >= 0 && offset < self->size);
  124.  
  125.   node_size = 1;
  126.   for (index = offset + self->size - 1; self->longest[index] ; index = PARENT(index))
  127.     node_size *= 2;
  128.  
  129.   return node_size;
  130. }
  131.  
  132. void buddy2_dump(struct buddy2* self) {
  133.   char canvas[65];
  134.   int i,j;
  135.   unsigned node_size, offset;
  136.  
  137.   if (self == NULL) {
  138.     printf("buddy2_dump: (struct buddy2*)self == NULL");
  139.     return;
  140.   }
  141.  
  142.   if (self->size > 64) {
  143.     printf("buddy2_dump: (struct buddy2*)self is too big to dump");
  144.     return;
  145.   }
  146.  
  147.   memset(canvas,'_', sizeof(canvas));
  148.   node_size = self->size * 2;
  149.  
  150.   for (i = 0; i < 2 * self->size - 1; ++i) {
  151.     if ( IS_POWER_OF_2(i+1) )
  152.       node_size /= 2;
  153.  
  154.     if ( self->longest[i] == 0 ) {
  155.       if (i >=  self->size - 1) {
  156.         canvas[i - self->size + 1] = '*';
  157.       }
  158.       else if (self->longest[LEFT_LEAF(i)] && self->longest[RIGHT_LEAF(i)]) {
  159.         offset = (i+1) * node_size - self->size;
  160.  
  161.         for (j = offset; j < offset + node_size; ++j)
  162.           canvas[j] = '*';
  163.       }
  164.     }
  165.   }
  166.   canvas[self->size] = '\0';
  167.   puts(canvas);
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement