コード例 #1
0
ファイル: linked_list.c プロジェクト: JoshCooley/irrd
/*-----------------------------------------------------------
 *  Name: 	LL_RemoveFn()
 *  Created:	Fri Sep  2 03:43:24 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	removes an item from the list,
 *              destroying it with function fn
 */
void LL_RemoveFn(LINKED_LIST *ll, DATA_PTR data, LL_DestroyProc destroy)
{
   if (ll->attr & LL_Intrusive) {
      if (NextP(ll, data)) PrevP(ll, NextP(ll, data)) = PrevP(ll, data);
      else ll->tail.data = PrevP(ll, data);
      if (PrevP(ll, data)) NextP(ll, PrevP(ll, data)) = NextP(ll, data);
      else ll->head.data = NextP(ll, data);
   }
   else { /* Container */
      LL_CONTAINER *cont;
      LLMacro_GetContainer(ll, cont, data);
      if (!cont) {
	 return;
      }
      if (ll->last == cont) { /* last can no longer point to this item  */
	 if (cont->prev) ll->last = cont->prev;
	 else ll->last = cont->next;
      }
      if (cont->next) cont->next->prev = cont->prev;
      else ll->tail.cont = cont->prev;
      if (cont->prev) cont->prev->next = cont->next;
      else ll->head.cont = cont->next;
      irrd_free(cont);
   }
   ll->count--;

   if (destroy) { (destroy)(data); }
}
コード例 #2
0
ファイル: linked_list.c プロジェクト: JoshCooley/irrd
/*-----------------------------------------------------------
 *  Name: 	LList_GetNext()
 *  Created:	Fri Sep  2 20:22:52 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	gets the next item on a list
 */
DATA_PTR LList_GetNext(LINKED_LIST *ll, DATA_PTR data)
{
   DATA_PTR ret;

   if (ll->attr & LL_Intrusive) {
      if (data) {
	 ret = NextP(ll, data);
      }
      else {
	 ret = ll->head.data;
      }
   }
   else {
      LL_CONTAINER *cont = NULL;
      if (data) {
	 LLMacro_GetContainer(ll, cont, data);
	 ll->last = cont->next;
	 if (cont->next) ret = cont->next->data;
	 else            ret = NULL;
      }
      else {
	 ll->last = ll->head.cont;
	 if (ll->head.cont) ret = ll->head.cont->data;
	 else               ret = NULL;
      }
   }

   return(ret);
}
コード例 #3
0
ファイル: linked_list.c プロジェクト: JoshCooley/irrd
/*-----------------------------------------------------------
 *  Name: 	LL_InsertAfter()
 *  Created:	Fri Sep  2 01:51:07 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	inserts a data element after another elt.
 *              before is the item "before me" or
 *              the item which i am to follow
 *              i.e. i am the item after BEFORE
 */
DATA_PTR LL_InsertAfter(LINKED_LIST *ll, DATA_PTR data, DATA_PTR before)
{
   if (ll->attr & LL_Intrusive) {
      DATA_PTR after;
      if (before) {
	 after = NextP(ll, before);
      }
      else { /* if !before */
	 after = ll->head.data;
      }
      LLMacro_IntrPlaceBetween(ll, data, before, after);
   }
   else { /* Container */
      LL_CONTAINER *after_cont, *before_cont, *cont;
      cont = irrd_malloc(sizeof(LL_CONTAINER));
      if (!cont) {
	 return(NULL);
      }
      if (before) {
	 LLMacro_GetContainer(ll, before_cont, before);
	 after_cont = before_cont->next;
      }
      else {
	 after_cont = ll->head.cont;
	 before_cont = NULL;
      }
      cont->data = data;
      LLMacro_ContPlaceBetween(ll, cont, before_cont, after_cont);
      ll->last = cont;
   }
   ll->count++;

   return(data);
}
コード例 #4
0
ファイル: hash.c プロジェクト: deepfield/MRT
/*-----------------------------------------------------------
 *  Name: 	HASH_ClearFn()
 *  Created:	Thu Sep  8 14:56:40 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	clears all items from a hash table
 */
void HASH_ClearFn(HASH_TABLE* h, HASH_DestroyProc destroy)
{
   int index;
#ifdef HASH_DEBUG
   if (!h) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_Clear()"); }
      return;
   }
#endif
   if (h->attr & HASH_Intrusive) {
      DATA_PTR data;
      for (index = 0; index < h->size; index++) { /* Run thru all the indicies */
	 while ((data = h->array.data[index])) { /* each item on list */
	    h->array.data[index] = NextP(h, data);
#ifdef HASH_DEBUG
	    NextP(h, data) = NULL;
#endif
	    if (destroy) { (destroy)(data); }
	 }
      }
   }
   else {
      HASH_CONTAINER *cont;
      for (index = 0; index < h->size; index++) { /* Run thru all the indicies */
	 while ((cont = h->array.cont[index])) { /* each item on list */
	    h->array.cont[index] = cont->next;
	    if (destroy) { (destroy)(cont->data); }
#ifdef HASH_DEBUG
	    cont->next = NULL;
	    cont->data = NULL;
#endif
	    Delete(cont);
	 }
      }
   }
   h->count = 0;
#ifdef HASH_DEBUG
   if (h->attr & HASH_ReportChange) {
      printf("HASH TABLE: 0x%.8x Clear(0x%.8x)\n", h, destroy);
   }
#endif

#ifdef _HASH_INTERNAL_DEBUG
   HASH_Verify(h);
#endif

}
コード例 #5
0
ファイル: hash.c プロジェクト: deepfield/MRT
/*-----------------------------------------------------------
 *  Name: 	HASH_ToArray()
 *  Created:	Thu Sep  8 23:49:47 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	reallocates array and coverts the hash table into it
 */
DATA_PTR *HASH_ToArray(HASH_TABLE *h, DATA_PTR *array, unsigned *size)
{
   unsigned index;
   unsigned array_index = 0;

#ifdef HASH_DEBUG
   if (!h) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_ToArray()"); }
   }
#endif

   if (!array) { 
      array = NewArray(DATA_PTR, h->count);
      if (!array) {
	 if (HASH_Handler) { (HASH_Handler)(h, HASH_MemoryErr, "HASH_ToArray()"); }
	 return(NULL);
      }
   }

   if (h->attr & HASH_Intrusive) {
      DATA_PTR data;
      for (index = 0; index < h->size; index++) {
	 for (data = h->array.data[index]; data; data = NextP(h, data)) {
	    array[array_index++] = data;
	 }
      }
   }
   else {
      HASH_CONTAINER *cont;
      for (index = 0; index < h->size; index++) {
	 for (cont = h->array.cont[index]; cont; cont = cont->next) {
	    array[array_index++] = cont->data;
	 }
      }
   }
#ifdef HASH_DEBUG
   if (h->attr & HASH_ReportAccess) {
      printf("HASH TABLE: 0x%.8x ToArray(0x%.8x, %u) count\n", h, array, h->count);
   }
#endif
   
   if (size) *size = h->count;

#ifdef _HASH_INTERNAL_DEBUG
   HASH_Verify(h);
#endif

   return(array);
}
コード例 #6
0
ファイル: hash.c プロジェクト: deepfield/MRT
/*-----------------------------------------------------------
 *  Name: 	HASH_Lookup()
 *  Created:	Thu Sep  8 20:23:56 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	looks up an item in the hash table
 */
DATA_PTR HASH_Lookup(HASH_TABLE* h, DATA_PTR key)
{
   unsigned index;
   DATA_PTR data;
#ifdef HASH_DEBUG
   if (!h || !key) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_Lookup()"); }
      return(NULL);
   }
#endif
   index = (h->hash)(key, h->size);
#ifdef HASH_DEBUG
   if (index >= h->size) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadIndex, "HASH_Lookup()"); }
      return(NULL);
   }
#endif
   
   if (h->attr & HASH_Intrusive) {
      for (data = h->array.data[index]; data; data = NextP(h, data)) {
	 if ((h->lookup)(KeyP(h, data), key)) break;
      }
   }
   else {
      HASH_CONTAINER *cont;
      for (cont = h->array.cont[index]; cont; cont = cont->next) {
	 if ((h->lookup)(KeyP(h, cont->data), key)) break;
      }
      if (cont) data = cont->data;
      else data = NULL;
   }
#ifdef HASH_DEBUG
   if (h->attr & HASH_ReportAccess) {
      if (data) printf("HASH TABLE: 0x%.8x Lookup(0x%.8x) = 0x%.8x\n", h, key, data);
      else      printf("HASH TABLE: 0x%.8x Lookup(0x%.8x) = NULL\n", h, key);
   }
#endif

#ifdef _HASH_INTERNAL_DEBUG
   HASH_Verify(h);
#endif

   return(data);
}
コード例 #7
0
ファイル: hash.c プロジェクト: deepfield/MRT
/*-----------------------------------------------------------
 *  Name: 	HASH_ProcessPlus()
 *  Created:	Thu Sep  8 20:42:48 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	process a hash table with second argument
 */
void HASH_ProcessPlus(HASH_TABLE *h, HASH_ProcessPlusProc fn, DATA_PTR arg2)
{
   unsigned index;

#ifdef HASH_DEBUG
   if (!h || !fn) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_ProcessPlus()"); }
      return;
   }
   if (h->attr & HASH_ReportAccess) {
      printf("HASH TABLE: 0x%.8x ProcessPlus(0x%.8x, 0x%.8x) started\n", h, fn, arg2);
   }
#endif
   
   if (h->attr & HASH_Intrusive) {
      DATA_PTR data;
      for (index = 0; index < h->size; index++) {
	 for (data = h->array.data[index]; data; data = NextP(h, data)) {
	    (fn)(data, arg2);
	 }
      }
   }
   else {
      HASH_CONTAINER *cont;
      for (index = 0; index < h->size; index++) {
	 for (cont = h->array.cont[index]; cont; cont = cont->next) {
	    (fn)(cont->data, arg2);
	 }
      }
   }
   
#ifdef HASH_DEBUG
   if (h->attr & HASH_ReportAccess) {
      printf("HASH TABLE: 0x%.8x ProcessPlus(0x%.8x, 0x%.8x) complete\n", h, fn, arg2);
   }
#endif

#ifdef _HASH_INTERNAL_DEBUG
   HASH_Verify(h);
#endif

}
コード例 #8
0
ファイル: hash.c プロジェクト: deepfield/MRT
/*-----------------------------------------------------------
 *  Name: 	HASH_ToLinkedList()
 *  Created:	Fri Sep  9 00:01:14 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	converts a hash table to a linked list
 */
LINKED_LIST *HASH_ToLinkedList(HASH_TABLE *h, LINKED_LIST *ll)
{
   unsigned index;
   
#ifdef HASH_DEBUG
   if (!h) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_ToLinkedList()"); }
   }
#endif

   if (!ll) ll = LL_Create(0);

   if (h->attr & HASH_Intrusive) {
      DATA_PTR data;
      for (index = 0; index < h->size; index++) {
	 for (data = h->array.data[index]; data; data = NextP(h, data)) {
	    LL_Add(ll, data);
	 }
      }
   }
   else {
      HASH_CONTAINER *cont;
      for (index = 0; index < h->size; index++) {
	 for (cont = h->array.cont[index]; cont; cont = cont->next) {
	    LL_Add(ll, cont->data);
	 }
      }
   }
#ifdef HASH_DEBUG
   if (h->attr & HASH_ReportAccess) {
      printf("HASH TABLE: 0x%.8x ToLinkedList(0x%.8x) complete\n", h, ll);
   }
#endif

#ifdef _HASH_INTERNAL_DEBUG
   HASH_Verify(h);
#endif

   return(ll);
}   
コード例 #9
0
ファイル: hash.c プロジェクト: deepfield/MRT
/*-----------------------------------------------------------
 *  Name: 	HASH_ReHash()
 *  Created:	Thu Sep  8 17:09:25 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	re-hashes an item, due to change in key.
 */
void HASH_ReHash(HASH_TABLE *h, DATA_PTR data, DATA_PTR old_key)
{
   unsigned index;
   DATA_PTR key;
   
#ifdef HASH_DEBUG
   if (!h || !data || !old_key) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_ReHash()"); }
      return;
   }
#endif
   
   key = KeyP(h, data);

#ifdef HASH_DEBUG
   if (!key) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_ReHash()"); }
      return;
   }
#endif

   index = (h->hash)(old_key, h->size);
#ifdef HASH_DEBUG
   if (index >= h->size) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadIndex, "HASH_ReHash()"); }
      return;
   }
#endif

   if (h->attr & HASH_Intrusive) {
      DATA_PTR prev, tmp;
      for (tmp = h->array.data[index], prev = NULL; tmp && tmp != data; prev = tmp, tmp = NextP(h, tmp));
#ifdef HASH_DEBUG
      if (tmp) {
	 if (HASH_Handler) { (HASH_Handler)(h, HASH_NoMember, "HASH_ReHash()"); }
	 return;
      }
#endif
      if (prev) { NextP(h, prev) = NextP(h, data); }
      else { h->array.data[index] = NextP(h, data); }
      NextP(h, data) = NULL;
      index = (h->hash)(key, h->size);
#ifdef HASH_DEBUG
      if (index >= h->size) {
	 if (HASH_Handler) { (HASH_Handler)(h, HASH_BadIndex, "HASH_ReHash()"); }
	 return;
      }
#endif
      if (h->array.data[index]) NextP(h, data) = h->array.data[index];
      h->array.data[index] = data;
   }
   else {
      HASH_CONTAINER *prev, *tmp;
      for (tmp = h->array.cont[index], prev = NULL; tmp && tmp->data != data; prev = tmp, tmp = tmp->next);
#ifdef HASH_DEBUG
      if (tmp) {
	 if (HASH_Handler) { (HASH_Handler)(h, HASH_NoMember, "HASH_Remove()"); }
	 return;
      }
#endif
      if (prev) { prev->next = tmp->next; }
      else { h->array.cont[index] = tmp->next; }
      tmp->next = NULL;
      index = (h->hash)(key, h->size);
#ifdef HASH_DEBUG
      if (index >= h->size) {
	 if (HASH_Handler) { (HASH_Handler)(h, HASH_BadIndex, "HASH_Remove()"); }
	 return;
      }
#endif
      if (h->array.cont[index]) tmp->next = h->array.cont[index];
      h->array.cont[index] = tmp;
   }

#ifdef HASH_DEBUG
   if (h->attr & HASH_ReportChange) {
      printf("HASH TABLE: 0x%.8x ReHash(0x%.8x, 0x%.8x, 0x%.8x)\n",
	     h, data, old_key, key);
   }
#endif
   
#ifdef _HASH_INTERNAL_DEBUG
   HASH_Verify(h);
#endif

}
コード例 #10
0
ファイル: hash.c プロジェクト: deepfield/MRT
/*-----------------------------------------------------------
 *  Name: 	HASH_RemoveByKeyFn()
 *  Created:	Thu Sep  8 16:11:12 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	removes an item from a hash table given key <key>
 */
void HASH_RemoveByKeyFn(HASH_TABLE *h, DATA_PTR key, HASH_DestroyProc destroy)
{
   unsigned index;
   DATA_PTR data;
   
#ifdef HASH_DEBUG
   if (!h || !key) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_RemoveByKey()"); }
      return;
   }
#endif

   index = (h->hash)(key, h->size);
#ifdef HASH_DEBUG
   if (index >= h->size) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadIndex, "HASH_RemoveByKey()"); }
      return;
   }
#endif

   if (h->attr & HASH_Intrusive) {
      DATA_PTR prev;
      for (data = h->array.data[index], prev = NULL; data; prev = data, data = NextP(h, data)) {
	 if ((h->lookup)(KeyP(h, data), key)) break; /* found it */
      }
#ifdef HASH_DEBUG
      if (!data) {
	 if (HASH_Handler) { (HASH_Handler)(h, HASH_NoMember, "HASH_RemoveByKey()"); }
	 return;
      }
#endif
      if (prev) { NextP(h, prev) = NextP(h, data); }
      else { h->array.data[index] = NextP(h, data); }
#ifdef HASH_DEBUG
      NextP(h, data) = NULL;
#endif
      if (destroy) { (destroy)(data); }
   }
   else {
      HASH_CONTAINER *cont, *prev;
      for (cont = h->array.cont[index], prev = NULL; cont; prev = cont, cont = cont->next) {
	 if ((h->lookup)(KeyP(h, cont->data), key)) break;  /* Found it */
      }
#ifdef HASH_DEBUG
      if (!cont) {
	 if (HASH_Handler) { (HASH_Handler)(h, HASH_NoMember, "HASH_Remove()"); }
	 return;
      }
#endif
      if (!cont) /* JW 6/1/98 fix for case when item not found */
	return;
      if (prev) { prev->next = cont->next; }
      else { h->array.cont[index] = cont->next; }
      data = cont->data;
      if (destroy) { (destroy)(cont->data); }
#ifdef HASH_DEBUG
      cont->next = NULL;
      cont->data = NULL;
#endif
      Delete(cont);
   }
   h->count--;
   
#ifdef HASH_DEBUG
   if (h->attr & HASH_ReportChange) {
      printf("HASH TABLE: 0x%.8x RemoveByKey(0x%.8x, 0x%.8x) %u => 0x%.8x, count = %u\n",
	     h, key, destroy, index, data, h->count);
   }
#endif
   
#ifdef _HASH_INTERNAL_DEBUG
   HASH_Verify(h);
#endif

}
コード例 #11
0
ファイル: hash.c プロジェクト: deepfield/MRT
/*-----------------------------------------------------------
 *  Name: 	HASH_RemoveFn()
 *  Created:	Thu Sep  8 16:11:12 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	removes an item from a hash table given key <key>
 */
void HASH_RemoveFn(HASH_TABLE *h, DATA_PTR data, HASH_DestroyProc destroy)
{
   unsigned index;
   
#ifdef HASH_DEBUG
   if (!h || !data) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_Remove()"); }
      return;
   }
#endif

   index = (h->hash)(KeyP(h, data), h->size);
#ifdef HASH_DEBUG
   if (index >= h->size) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadIndex, "HASH_Remove()"); }
      return;
   }
#endif

   if (h->attr & HASH_Intrusive) {
      DATA_PTR tmp, prev;
      /* Find Prev */
      for (tmp = h->array.data[index], prev = NULL; tmp; prev = tmp, tmp = NextP(h, tmp)) {
	 if (tmp == data) break;
      }
#ifdef HASH_DEBUG
      if (!tmp) {
	 if (HASH_Handler) { (HASH_Handler)(h, HASH_NoMember, "HASH_Remove()"); }
	 return;
      }
#endif
      if (prev) { NextP(h, prev) = NextP(h, data); }
      else { h->array.data[index] = NextP(h, data); }
#ifdef HASH_DEBUG
      NextP(h, data) = NULL;
#endif
      if (destroy) { (destroy)(data); }
   }
   else {
      HASH_CONTAINER *cont, *prev;
      for (cont = h->array.cont[index], prev = NULL; cont; prev = cont, cont = cont->next) {
	 if (cont->data == data) break;
      }
#ifdef HASH_DEBUG
      if (!cont) {
	 if (HASH_Handler) { (HASH_Handler)(h, HASH_NoMember, "HASH_Remove()"); }
	 return;
      }
#endif
      if (prev) { prev->next = cont->next; }
      else { h->array.cont[index] = cont->next; }
      if (destroy) { (destroy)(cont->data); }
#ifdef HASH_DEBUG
      cont->next = NULL;
      cont->data = NULL;
#endif
      Delete(cont);
   }
   h->count--;
   
#ifdef HASH_DEBUG
   if (h->attr & HASH_ReportChange) {
      printf("HASH TABLE: 0x%.8x Remove(0x%.8x, 0x%.8x) count = %u\n",
	     h, data, destroy, h->count);
   }
#endif
   
#ifdef _HASH_INTERNAL_DEBUG
   HASH_Verify(h);
#endif

}
コード例 #12
0
ファイル: hash.c プロジェクト: deepfield/MRT
/*-----------------------------------------------------------
 *  Name: 	HASH_Insert()
 *  Created:	Thu Sep  8 15:37:07 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	insert an item into a table
 */
DATA_PTR HASH_Insert(HASH_TABLE* h, DATA_PTR data)
{
   DATA_PTR key;
   unsigned index;

#ifdef HASH_DEBUG
   if (!h || !data) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_Insert()"); }
      return(NULL);
   }
#endif
   
   key = KeyP(h, data);
   
#ifdef HASH_DEBUG
   if (!key) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_Insert()"); }
      return(NULL);
   }
#endif

   /* check if we are going to have to re-hash the entire thing (dynamic) */
   if ((h->resize) && (h->count >= (h->resize)*(h->size))) {
      /* we must resize */
      unsigned new_size = h->size*2;
      HASH_ChangeSize(h, new_size);
   }
   
   index = (h->hash)(key, h->size);
#ifdef HASH_DEBUG
   if (index >= h->size) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadIndex, "HASH_Insert()"); }
      return(NULL);
   }
#endif

   if (h->attr & HASH_Intrusive) {
      NextP(h, data) = h->array.data[index];
      h->array.data[index] = data;
   }
   else {
      HASH_CONTAINER *cont = New(HASH_CONTAINER);
      if (!cont) {
	 if (HASH_Handler) { (HASH_Handler)(h, HASH_MemoryErr, "HASH_Insert()"); }
	 return(NULL);
      }
      cont->data = data;
      cont->next = h->array.cont[index];
      h->array.cont[index] = cont;
   }
   h->count++;
   
#ifdef HASH_DEBUG
   if (h->attr & HASH_ReportChange) {
      printf("HASH TABLE: 0x%.8x Insert(0x%.8x, 0x%.8x) (%u) count = %u\n",
	     h, data, key, index, h->count);
   }
#endif
   
#ifdef _HASH_INTERNAL_DEBUG
   HASH_Verify(h);
#endif

   return(data);
   
}
コード例 #13
0
ファイル: hash.c プロジェクト: deepfield/MRT
/*-----------------------------------------------------------
 *  Name: 	HASH_ChangeSize()
 *  Created:	Mon Sep 26 20:09:16 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	modifies the size of the hash table to x
 */
void HASH_ChangeSize(HASH_TABLE *h, unsigned size)
{
   unsigned index;
   
#ifdef HASH_DEBUG
   if (!h || !size) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_ChangeSize()"); }
   }
   if (h->attr & HASH_ReportChange) {
      printf("HASH TABLE: 0x%.8x Resizing to %u slots\n", h, size);
   }
#endif
   if (h->attr & HASH_Intrusive) {
      DATA_PTR *array = NewArray(DATA_PTR, size);
      DATA_PTR moving;
      unsigned old;
      if (!array) {
	 if (HASH_Handler) { (HASH_Handler)(h, HASH_MemoryErr, "HASH_ChangeSize()"); }
	 return;
      }
      else {
	 for (old = 0; old < h->size; old++) {
	    while ((moving = h->array.data[old])) {
	       h->array.data[old] = NextP(h, moving);
	       index = (h->hash)(KeyP(h, moving), size);
#ifdef HASH_DEBUG
	       if (index >= size) {
		  if (HASH_Handler) { (HASH_Handler)(h, HASH_BadIndex, "HASH_ChangeSize()"); }
		  return;
	       }
#endif
	       NextP(h, moving) = array[index];
	       array[index] = moving;
	    }
	 }
	 Delete(h->array.data);
	 h->array.data = array;
      }
   }
   else {
      HASH_CONTAINER **array = NewArray(HASH_CONTAINER*, size);
      HASH_CONTAINER *moving;
      unsigned old;
      if (!array) {
	 if (HASH_Handler) { (HASH_Handler)(h, HASH_MemoryErr, "HASH_ChangeSize()"); }
	 return;
      }
      else {
	 for (old = 0; old < h->size; old++) {
	    while ((moving = h->array.cont[old])) {
	       h->array.cont[old] = moving->next;
	       index = (h->hash)(KeyP(h, moving->data), size);
#ifdef HASH_DEBUG
	       if (index >= size) {
		  if (HASH_Handler) { (HASH_Handler)(h, HASH_BadIndex, "HASH_ChangeSize()"); }
		  return;
	       }
#endif
	       moving->next = array[index];
	       array[index] = moving;
	    }
	 }
	 Delete(h->array.cont);
	 h->array.cont = array;
      }
   }
   h->size = size;
}
コード例 #14
0
ファイル: hash.c プロジェクト: deepfield/MRT
/*-----------------------------------------------------------
 *  Name: 	HASH_GetNext()
 *  Created:	Thu Sep  8 20:46:38 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	iteration support for hash tables
 *  Modified to have last_cont in HASH_TABLE, instead of static.
 *  still we CAN NOT do HASH_Iterate on the same hash_table, though.
 */
DATA_PTR HASH_GetNext(HASH_TABLE *h, DATA_PTR current)
{
   unsigned        index;
   DATA_PTR        data;
   HASH_CONTAINER *cont = NULL;

#ifdef HASH_DEBUG
   if (!h) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_Iterate()"); }
      return(NULL);
   }
#endif

   if (!current) { /* Find first item */

      for (index = 0; ((index < h->size) && (!(h->array.data[index]))); index++);
      if (index < h->size) {
	 if (h->attr & HASH_Intrusive) {
	    data = h->array.data[index];
	 }
	 else {
	    cont = h->array.cont[index];
	    data = cont->data;
	 }
      }
      else {
	 data = NULL; /* table is empty */
      }
   }
   else {
      if (h->attr & HASH_Intrusive) {
	 data = NextP(h, current);
	 if (!data) { /* current was last one on last_index */
	    index = (h->hash)(KeyP(h, current), h->size);
#ifdef HASH_DEBUG
	    if (index >= h->size) {
	       if (HASH_Handler) { (HASH_Handler)(h, HASH_BadIndex, "HASH_Iterate()"); }
	       return(NULL);
	    }
#endif
	    for (index++; ((index < h->size) && (!(h->array.data[index]))); index++);
	    if (index < h->size) data = h->array.data[index];
	    else data = NULL; /* current was last one in table */
	 }
      }
      else {
#if	0
	 HASH_CONTAINER *cont;
#endif
	 if ((h->last_cont) && (h->last_cont->data == current)) cont = h->last_cont;
	 else { /* LAST_CONTAINER is messed up ?? */
	    index = (h->hash)(KeyP(h, current), h->size);  /* get index of current and find its cont */
#ifdef HASH_DEBUG
	    if (index >= h->size) {
	       if (HASH_Handler) { (HASH_Handler)(h, HASH_BadIndex, "HASH_Iterate()"); }
	       return(NULL);
	    }
#endif
	    for (cont = h->array.cont[index]; 
	    	 ((cont) && (cont->data != current)); 
		 cont = cont->next);
	 }
#ifdef HASH_DEBUG
	 if (!cont) { /* failed to find current's container must have been deleted!!!! */
	    if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_Iterate()"); }
	    return(NULL);
	 }
#endif
	 if (!cont->next) { /* current was last one in index */
	    index = (h->hash)(KeyP(h, cont->data), h->size);
	    for (index++; ((index < h->size) && (!(h->array.cont[index]))); index++);
	    if (index < h->size) cont = h->array.cont[index];
	    else cont = NULL; /* current is the absolute LAST */
	 }
	 else {
	    cont = cont->next;
	 }
	 if (cont) data = cont->data;
	 else data = NULL;
      }
   }
      h->last_cont = cont;
#ifdef HASH_DEBUG
   if (h->attr & HASH_ReportAccess) {
      printf("HASH TABLE: 0x%.8x Iterate() currently at 0x%.8x\n", h, data);
   }
#endif

#ifdef _HASH_INTERNAL_DEBUG
   HASH_Verify(h);
#endif

   return(data);
}