#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#undef assert
#define assert(X)


/* In the current implementation, each slab in the pool has NODES_PER_SLAB
 * nodes unless the isSingleArray flag is set in which case it contains a
 * single array of size ArraySize. Small arrays (size <= NODES_PER_SLAB) are
 * still allocated in the slabs of size NODES_PER_SLAB
 */
#define NODES_PER_SLAB 512 

typedef struct PoolTy {
  void    *Data;
  unsigned NodeSize;
  unsigned FreeablePool; /* Set to false if the memory from this pool cannot be
			    freed before destroy*/
  
} PoolTy;

/* PoolSlab Structure - Hold NODES_PER_SLAB objects of the current node type.
 *   Invariants: FirstUnused <= LastUsed+1
 */
typedef struct PoolSlab {
  unsigned FirstUnused;     /* First empty node in slab    */
  int LastUsed;             /* Last allocated node in slab */
  struct PoolSlab *Next;
  unsigned char AllocatedBitVector[NODES_PER_SLAB/8];
  unsigned char StartOfAllocation[NODES_PER_SLAB/8];

  unsigned isSingleArray;   /* If this slab is used for exactly one array */
  /* The array is allocated from the start to the end of the slab */
  unsigned ArraySize;       /* The size of the array allocated */ 

  char Data[1];   /* Buffer to hold data in this slab... variable sized */

} PoolSlab;

#define NODE_ALLOCATED(POOLSLAB, NODENUM) \
   ((POOLSLAB)->AllocatedBitVector[(NODENUM) >> 3] & (1 << ((NODENUM) & 7)))
#define MARK_NODE_ALLOCATED(POOLSLAB, NODENUM) \
   (POOLSLAB)->AllocatedBitVector[(NODENUM) >> 3] |= 1 << ((NODENUM) & 7)
#define MARK_NODE_FREE(POOLSLAB, NODENUM) \
   (POOLSLAB)->AllocatedBitVector[(NODENUM) >> 3] &= ~(1 << ((NODENUM) & 7))
#define ALLOCATION_BEGINS(POOLSLAB, NODENUM) \
   ((POOLSLAB)->StartOfAllocation[(NODENUM) >> 3] & (1 << ((NODENUM) & 7)))
#define SET_START_BIT(POOLSLAB, NODENUM) \
   (POOLSLAB)->StartOfAllocation[(NODENUM) >> 3] |= 1 << ((NODENUM) & 7)
#define CLEAR_START_BIT(POOLSLAB, NODENUM) \
   (POOLSLAB)->StartOfAllocation[(NODENUM) >> 3] &= ~(1 << ((NODENUM) & 7))


/* poolinit - Initialize a pool descriptor to empty
 */
void poolinit(PoolTy *Pool, unsigned NodeSize) {
  if (!Pool) {
    printf("Null pool pointer passed into poolinit!\n");
    exit(1);
  }

  Pool->NodeSize = NodeSize;
  Pool->Data = 0;

  Pool->FreeablePool = 1;

}

void poolmakeunfreeable(PoolTy *Pool) {
  if (!Pool) {
    printf("Null pool pointer passed in to poolmakeunfreeable!\n");
    exit(1);
  }

  Pool->FreeablePool = 0;
}

/* pooldestroy - Release all memory allocated for a pool
 */
void pooldestroy(PoolTy *Pool) {
  PoolSlab *PS;
  if (!Pool) {
    printf("Null pool pointer passed in to pooldestroy!\n");
    exit(1);
  }

  PS = (PoolSlab*)Pool->Data;
  while (PS) {
    PoolSlab *Next = PS->Next;
    free(PS);
    PS = Next;
  }
}

static void *FindSlabEntry(PoolSlab *PS, unsigned NodeSize) {
  /* Loop through all of the slabs looking for one with an opening */
  for (; PS; PS = PS->Next) {

    /* If the slab is a single array, go on to the next slab */
    /* Don't allocate single nodes in a SingleArray slab */
    if (PS->isSingleArray) 
      continue;

    /* Check to see if there are empty entries at the end of the slab... */
    if (PS->LastUsed < NODES_PER_SLAB-1) {
      /* Mark the returned entry used */
      MARK_NODE_ALLOCATED(PS, PS->LastUsed+1);
      SET_START_BIT(PS, PS->LastUsed+1);

      /* If we are allocating out the first unused field, bump its index also */
      if (PS->FirstUnused == PS->LastUsed+1)
        PS->FirstUnused++;

      /* Return the entry, increment LastUsed field. */
      return &PS->Data[0] + ++PS->LastUsed * NodeSize;
    }

    /* If not, check to see if this node has a declared "FirstUnused" value that
     * is less than the number of nodes allocated...
     */
    if (PS->FirstUnused < NODES_PER_SLAB) {
      /* Successfully allocate out the first unused node */
      unsigned Idx = PS->FirstUnused;

      MARK_NODE_ALLOCATED(PS, Idx);
      SET_START_BIT(PS, Idx);

      /* Increment FirstUnused to point to the new first unused value... */
      do {
        ++PS->FirstUnused;
      } while (PS->FirstUnused < NODES_PER_SLAB &&
               NODE_ALLOCATED(PS, PS->FirstUnused));

      return &PS->Data[0] + Idx*NodeSize;
    }
  }

  /* No empty nodes available, must grow # slabs! */
  return 0;
}

char *poolalloc(PoolTy *Pool) {
  unsigned NodeSize;
  PoolSlab *PS;
  void *Result;

  if (!Pool) {
    printf("Null pool pointer passed in to poolalloc!\n");
    exit(1);
  }
  
  NodeSize = Pool->NodeSize;
  // Return if this pool has size 0
  if (NodeSize == 0)
    return 0;

  PS = (PoolSlab*)Pool->Data;

  if ((Result = FindSlabEntry(PS, NodeSize)))
    return Result;

  /* Otherwise we must allocate a new slab and add it to the list */
  PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1);

  if (!PS) {
    printf("poolalloc: Could not allocate memory!");
    exit(1);
  }

  /* Initialize the slab to indicate that the first element is allocated */
  PS->FirstUnused = 1;
  PS->LastUsed = 0;
  /* This is not a single array */
  PS->isSingleArray = 0;
  PS->ArraySize = 0;
  
  MARK_NODE_ALLOCATED(PS, 0);
  SET_START_BIT(PS, 0);

  /* Add the slab to the list... */
  PS->Next = (PoolSlab*)Pool->Data;
  Pool->Data = PS;
  return &PS->Data[0];
}

void poolfree(PoolTy *Pool, char *Node) {
  unsigned NodeSize, Idx;
  PoolSlab *PS;
  PoolSlab **PPS;
  unsigned idxiter;

  if (!Pool) {
    printf("Null pool pointer passed in to poolfree!\n");
    exit(1);
  }

  NodeSize = Pool->NodeSize;

  // Return if this pool has size 0
  if (NodeSize == 0)
    return;

  PS = (PoolSlab*)Pool->Data;
  PPS = (PoolSlab**)&Pool->Data;

  /* Search for the slab that contains this node... */
  while (&PS->Data[0] > Node || &PS->Data[NodeSize*NODES_PER_SLAB-1] < Node) {
    if (!PS) { 
      printf("poolfree: node being free'd not found in allocation pool specified!\n");
      exit(1);
    }

    PPS = &PS->Next;
    PS = PS->Next;
  }

  /* PS now points to the slab where Node is */

  Idx = (Node-&PS->Data[0])/NodeSize;
  assert(Idx < NODES_PER_SLAB && "Pool slab searching loop broken!");

  if (PS->isSingleArray) {

    /* If this slab is a SingleArray */

    if (Idx != 0) {
      printf("poolfree: Attempt to free middle of allocated array\n");
      exit(1);
    }
    if (!NODE_ALLOCATED(PS,0)) {
      printf("poolfree: Attempt to free node that is already freed\n");
      exit(1);
    }
    /* Mark this SingleArray slab as being free by just marking the first
       entry as free*/
    MARK_NODE_FREE(PS, 0);
  } else {
    
    /* If this slab is not a SingleArray */
    
    if (!ALLOCATION_BEGINS(PS, Idx)) { 
      printf("poolfree: Attempt to free middle of allocated array\n");
      exit(1);
    }

    /* Free the first node */
    if (!NODE_ALLOCATED(PS, Idx)) {
      printf("poolfree: Attempt to free node that is already freed\n");
      exit(1); 
    }
    CLEAR_START_BIT(PS, Idx);
    MARK_NODE_FREE(PS, Idx);
    
    // Free all nodes 
    idxiter = Idx + 1;
    while (idxiter < NODES_PER_SLAB && (!ALLOCATION_BEGINS(PS,idxiter)) && 
	   (NODE_ALLOCATED(PS, idxiter))) {
      MARK_NODE_FREE(PS, idxiter);
      ++idxiter;
    }

    /* Update the first free field if this node is below the free node line */
    if (Idx < PS->FirstUnused) PS->FirstUnused = Idx;
    
    /* If we are not freeing the last element in a slab... */
    if (idxiter - 1 != PS->LastUsed) {
      return;
    }

    /* Otherwise we are freeing the last element in a slab... shrink the
     * LastUsed marker down to last used node.
     */
    PS->LastUsed = Idx;
    do {
      --PS->LastUsed;
      /* Fixme, this should scan the allocated array an entire byte at a time 
       * for performance!
       */
    } while (PS->LastUsed >= 0 && (!NODE_ALLOCATED(PS, PS->LastUsed)));
    
    assert(PS->FirstUnused <= PS->LastUsed+1 &&
	   "FirstUnused field was out of date!");
  }
    
  /* Ok, if this slab is empty, we unlink it from the of slabs and either move
   * it to the head of the list, or free it, depending on whether or not there
   * is already an empty slab at the head of the list.
   */
  /* Do this only if the pool is freeable */
  if (Pool->FreeablePool) {
    if (PS->isSingleArray) {
      /* If it is a SingleArray, just free it */
      *PPS = PS->Next;
      free(PS);
    } else if (PS->LastUsed == -1) {   /* Empty slab? */
      PoolSlab *HeadSlab;
      *PPS = PS->Next;   /* Unlink from the list of slabs... */
      
      HeadSlab = (PoolSlab*)Pool->Data;
      if (HeadSlab && HeadSlab->LastUsed == -1){/*List already has empty slab?*/
	free(PS);                               /*Free memory for slab */
      } else {
	PS->Next = HeadSlab;                    /*No empty slab yet, add this*/
	Pool->Data = PS;                        /*one to the head of the list */
      }
    }
  } else {
    /* Pool is not freeable for safety reasons */
    /* Leave it in the list of PoolSlabs as an empty PoolSlab */
    if (!PS->isSingleArray)
      if (PS->LastUsed == -1) {
	PS->FirstUnused = 0;
	
	/* Do not free the pool, but move it to the head of the list if there is
	   no empty slab there already */
	PoolSlab *HeadSlab;
	HeadSlab = (PoolSlab*)Pool->Data;
	if (HeadSlab && HeadSlab->LastUsed != -1) {
	  PS->Next = HeadSlab;
	  Pool->Data = PS;
	}
      }
  }
}

/* The poolallocarray version of FindSlabEntry */
static void *FindSlabEntryArray(PoolSlab *PS, unsigned NodeSize, 
				unsigned Size) {
  unsigned i;

  /* Loop through all of the slabs looking for one with an opening */
  for (; PS; PS = PS->Next) {
    
    /* For large array allocation */
    if (Size > NODES_PER_SLAB) {
      /* If this slab is a SingleArray that is free with size > Size, use it */
      if (PS->isSingleArray && !NODE_ALLOCATED(PS,0) && PS->ArraySize >= Size) {
	/* Allocate the array in this slab */
	MARK_NODE_ALLOCATED(PS,0); /* In a single array, only the first node
				      needs to be marked */
	return &PS->Data[0];
      } else
	continue;
    } else if (PS->isSingleArray)
      continue; /* Do not allocate small arrays in SingleArray slabs */

    /* For small array allocation */
    /* Check to see if there are empty entries at the end of the slab... */
    if (PS->LastUsed < NODES_PER_SLAB-Size) {
      /* Mark the returned entry used and set the start bit*/
      SET_START_BIT(PS, PS->LastUsed + 1);
      for (i = PS->LastUsed + 1; i <= PS->LastUsed + Size; ++i)
	MARK_NODE_ALLOCATED(PS, i);

      /* If we are allocating out the first unused field, bump its index also */
      if (PS->FirstUnused == PS->LastUsed+1)
        PS->FirstUnused += Size;

      /* Increment LastUsed */
      PS->LastUsed += Size;

      /* Return the entry */
      return &PS->Data[0] + (PS->LastUsed - Size + 1) * NodeSize;
    }

    /* If not, check to see if this node has a declared "FirstUnused" value
     * starting which Size nodes can be allocated
     */
    if (PS->FirstUnused < NODES_PER_SLAB - Size + 1 &&
	(PS->LastUsed < PS->FirstUnused || 
	 PS->LastUsed - PS->FirstUnused >= Size)) {
      unsigned Idx = PS->FirstUnused, foundArray;
      
      /* Check if there is a continuous array of Size nodes starting 
	 FirstUnused */
      foundArray = 1;
      for (i = Idx; (i < Idx + Size) && foundArray; ++i)
	if (NODE_ALLOCATED(PS, i))
	  foundArray = 0;

      if (foundArray) {
	/* Successfully allocate starting from the first unused node */
	SET_START_BIT(PS, Idx);
	for (i = Idx; i < Idx + Size; ++i)
	  MARK_NODE_ALLOCATED(PS, i);
	
	PS->FirstUnused += Size;
	while (PS->FirstUnused < NODES_PER_SLAB &&
               NODE_ALLOCATED(PS, PS->FirstUnused)) {
	  ++PS->FirstUnused;
	}
	return &PS->Data[0] + Idx*NodeSize;
      }
      
    }
  }

  /* No empty nodes available, must grow # slabs! */
  return 0;
}

char* poolallocarray(PoolTy* Pool, unsigned Size) {
  unsigned NodeSize;
  PoolSlab *PS;
  void *Result;
  unsigned i;

  if (!Pool) {
    printf("Null pool pointer passed to poolallocarray!\n");
    exit(1);
  }

  NodeSize = Pool->NodeSize;

  // Return if this pool has size 0
  if (NodeSize == 0)
    return 0;

  PS = (PoolSlab*)Pool->Data;

  if ((Result = FindSlabEntryArray(PS, NodeSize,Size)))
    return Result;

  /* Otherwise we must allocate a new slab and add it to the list */
  if (Size > NODES_PER_SLAB) {
    /* Allocate a new slab of size Size */
    PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*Size-1);
    if (!PS) {
      printf("poolallocarray: Could not allocate memory!\n");
      exit(1);
    }
    PS->isSingleArray = 1;
    PS->ArraySize = Size;
    MARK_NODE_ALLOCATED(PS, 0);
  } else {
    PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1);
    if (!PS) {
      printf("poolallocarray: Could not allocate memory!\n");
      exit(1);
    }

    /* Initialize the slab to indicate that the first element is allocated */
    PS->FirstUnused = Size;
    PS->LastUsed = Size - 1;
    
    PS->isSingleArray = 0;
    PS->ArraySize = 0;

    SET_START_BIT(PS, 0);
    for (i = 0; i < Size; ++i) {
      MARK_NODE_ALLOCATED(PS, i);
    }
  }

  /* Add the slab to the list... */
  PS->Next = (PoolSlab*)Pool->Data;
  Pool->Data = PS;
  return &PS->Data[0];
}
