nchashmap.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*********************************************************************
  2. * Copyright 1993, UCAR/Unidata
  3. * See netcdf/COPYRIGHT file for copying and redistribution conditions.
  4. * $Header: /upc/share/CVS/netcdf-3/libncdap3/nchashmap.c,v 1.4 2009/09/23 22:26:08 dmh Exp $
  5. *********************************************************************/
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "nchashmap.h"
  10. static ncelem ncDATANULL = (ncelem)0;
  11. #ifndef TRUE
  12. #define TRUE 1
  13. #endif
  14. #ifndef FALSE
  15. #define FALSE 0
  16. #endif
  17. #define DEFAULTALLOC 31
  18. NChashmap* nchashnew(void) {return nchashnew0(DEFAULTALLOC);}
  19. NChashmap* nchashnew0(int alloc)
  20. {
  21. NChashmap* hm;
  22. hm = (NChashmap*)malloc(sizeof(NChashmap));
  23. if(!hm) return NULL;
  24. hm->alloc = alloc;
  25. hm->table = (NClist**)malloc(hm->alloc*sizeof(NClist*));
  26. if(!hm->table) {free(hm); return NULL;}
  27. memset((void*)hm->table,0,hm->alloc*sizeof(NClist*));
  28. return hm;
  29. }
  30. int
  31. nchashfree(NChashmap* hm)
  32. {
  33. if(hm) {
  34. int i;
  35. for(i=0;i<hm->alloc;i++) {
  36. if(hm->table[i] != NULL) nclistfree(hm->table[i]);
  37. }
  38. free(hm->table);
  39. free(hm);
  40. }
  41. return TRUE;
  42. }
  43. /* Insert a <nchashid,ncelem> pair into the table*/
  44. /* Fail if already there*/
  45. int
  46. nchashinsert(NChashmap* hm, nchashid hash, ncelem value)
  47. {
  48. int i,offset,len;
  49. NClist* seq;
  50. ncelem* list;
  51. offset = (hash % hm->alloc);
  52. seq = hm->table[offset];
  53. if(seq == NULL) {seq = nclistnew(); hm->table[offset] = seq;}
  54. len = nclistlength(seq);
  55. list = nclistcontents(seq);
  56. for(i=0;i<len;i+=2,list+=2) {
  57. if(*list == hash) return FALSE;
  58. }
  59. nclistpush(seq,(ncelem)hash);
  60. nclistpush(seq,value);
  61. hm->size++;
  62. return TRUE;
  63. }
  64. /* Insert a <nchashid,ncelem> pair into the table*/
  65. /* Overwrite if already there*/
  66. int
  67. nchashreplace(NChashmap* hm, nchashid hash, ncelem value)
  68. {
  69. int i,offset,len;
  70. NClist* seq;
  71. ncelem* list;
  72. offset = (hash % hm->alloc);
  73. seq = hm->table[offset];
  74. if(seq == NULL) {seq = nclistnew(); hm->table[offset] = seq;}
  75. len = nclistlength(seq);
  76. list = nclistcontents(seq);
  77. for(i=0;i<len;i+=2,list+=2) {
  78. if(*list == hash) {list[1] = value; return TRUE;}
  79. }
  80. nclistpush(seq,(ncelem)hash);
  81. nclistpush(seq,value);
  82. hm->size++;
  83. return TRUE;
  84. }
  85. /* remove a nchashid*/
  86. /* return TRUE if found, false otherwise*/
  87. int
  88. nchashremove(NChashmap* hm, nchashid hash)
  89. {
  90. int i,offset,len;
  91. NClist* seq;
  92. ncelem* list;
  93. offset = (hash % hm->alloc);
  94. seq = hm->table[offset];
  95. if(seq == NULL) return TRUE;
  96. len = nclistlength(seq);
  97. list = nclistcontents(seq);
  98. for(i=0;i<len;i+=2,list+=2) {
  99. if(*list == hash) {
  100. nclistremove(seq,i+1);
  101. nclistremove(seq,i);
  102. hm->size--;
  103. if(nclistlength(seq) == 0) {nclistfree(seq); hm->table[offset] = NULL;}
  104. return TRUE;
  105. }
  106. }
  107. return FALSE;
  108. }
  109. /* lookup a nchashid; return DATANULL if not found*/
  110. /* (use hashlookup if the possible values include 0)*/
  111. ncelem
  112. nchashget(NChashmap* hm, nchashid hash)
  113. {
  114. ncelem value;
  115. if(!nchashlookup(hm,hash,&value)) return ncDATANULL;
  116. return value;
  117. }
  118. int
  119. nchashlookup(NChashmap* hm, nchashid hash, ncelem* valuep)
  120. {
  121. int i,offset,len;
  122. NClist* seq;
  123. ncelem* list;
  124. offset = (hash % hm->alloc);
  125. seq = hm->table[offset];
  126. if(seq == NULL) return TRUE;
  127. len = nclistlength(seq);
  128. list = nclistcontents(seq);
  129. for(i=0;i<len;i+=2,list+=2) {
  130. if(*list == hash) {if(valuep) {*valuep = list[1]; return TRUE;}}
  131. }
  132. return FALSE;
  133. }
  134. /* Return the ith pair; order is completely arbitrary*/
  135. /* Can be expensive*/
  136. int
  137. nchashith(NChashmap* hm, int index, nchashid* hashp, ncelem* elemp)
  138. {
  139. int i;
  140. if(hm == NULL) return FALSE;
  141. for(i=0;i<hm->alloc;i++) {
  142. NClist* seq = hm->table[i];
  143. int len = nclistlength(seq) / 2;
  144. if(len == 0) continue;
  145. if((index - len) < 0) {
  146. if(hashp) *hashp = (nchashid)nclistget(seq,index*2);
  147. if(elemp) *elemp = nclistget(seq,(index*2)+1);
  148. return TRUE;
  149. }
  150. index -= len;
  151. }
  152. return FALSE;
  153. }
  154. /* Return all the keys; order is completely arbitrary*/
  155. /* Can be expensive*/
  156. int
  157. nchashkeys(NChashmap* hm, nchashid** keylist)
  158. {
  159. int i,j,index;
  160. nchashid* keys;
  161. if(hm == NULL) return FALSE;
  162. if(hm->size == 0) {
  163. keys = NULL;
  164. } else {
  165. keys = (nchashid*)malloc(sizeof(nchashid)*hm->size);
  166. for(index=0,i=0;i<hm->alloc;i++) {
  167. NClist* seq = hm->table[i];
  168. for(j=0;j<nclistlength(seq);j+=2) {
  169. keys[index++] = (nchashid)nclistget(seq,j);
  170. }
  171. }
  172. }
  173. if(keylist) {*keylist = keys;}
  174. return TRUE;
  175. }