sym_table.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. #include "config.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include "logging.h"
  7. #include "mcell_structs.h"
  8. #include "sym_table.h"
  9. #include "react_output.h"
  10. #include "mem_util.h"
  11. #define hashsize(n) ((ub4)1<<(n))
  12. #define hashmask(n) (hashsize(n)-1)
  13. extern struct volume *world;
  14. /* ================ Bob Jenkin hash function ======================== */
  15. /*--------------------------------------------------------------------
  16. mix -- mix 3 32-bit values reversibly.
  17. For every delta with one or two bits set, and the deltas of all three
  18. high bits or all three low bits, whether the original value of a,b,c
  19. is almost all zero or is uniformly distributed,
  20. * If mix() is run forward or backward, at least 32 bits in a,b,c
  21. have at least 1/4 probability of changing.
  22. * If mix() is run forward, every bit of c will change between 1/3 and
  23. 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
  24. mix() was built out of 36 single-cycle latency instructions in a
  25. structure that could supported 2x parallelism, like so:
  26. a -= b;
  27. a -= c; x = (c>>13);
  28. b -= c; a ^= x;
  29. b -= a; x = (a<<8);
  30. c -= a; b ^= x;
  31. c -= b; x = (b>>13);
  32. ...
  33. Unfortunately, superscalar Pentiums and Sparcs can't take advantage
  34. of that parallelism. They've also turned some of those single-cycle
  35. latency instructions into multi-cycle latency instructions. Still,
  36. this is the fastest good hash I could find. There were about 2^^68
  37. to choose from. I only looked at a billion or so.
  38. --------------------------------------------------------------------*/
  39. #define mix(a,b,c) \
  40. { \
  41. a -= b; a -= c; a ^= (c>>13); \
  42. b -= c; b -= a; b ^= (a<<8); \
  43. c -= a; c -= b; c ^= (b>>13); \
  44. a -= b; a -= c; a ^= (c>>12); \
  45. b -= c; b -= a; b ^= (a<<16); \
  46. c -= a; c -= b; c ^= (b>>5); \
  47. a -= b; a -= c; a ^= (c>>3); \
  48. b -= c; b -= a; b ^= (a<<10); \
  49. c -= a; c -= b; c ^= (b>>15); \
  50. }
  51. /*--------------------------------------------------------------------
  52. hash() -- hash a variable-length key into a 32-bit value
  53. k : the key (the unaligned variable-length array of bytes)
  54. len : the length of the key, counting by bytes
  55. initval : can be any 4-byte value
  56. Returns a 32-bit value. Every bit of the key affects every bit of
  57. the return value. Every 1-bit and 2-bit delta achieves avalanche.
  58. About 6*len+35 instructions.
  59. The best hash table sizes are powers of 2. There is no need to do
  60. mod a prime (mod is sooo slow!). If you need less than 32 bits,
  61. use a bitmask. For example, if you need only 10 bits, do
  62. h = (h & hashmask(10));
  63. In which case, the hash table should have hashsize(10) elements.
  64. If you are hashing n strings (ub1 **)k, do it like this:
  65. for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
  66. By Bob Jenkins, 1996. [email protected]. You may use this
  67. code any way you wish, private, educational, or commercial. It's free.
  68. See http://burtleburtle.net/bob/hash/evahash.html
  69. Use for hash table lookup, or anything where one collision in 2^^32 is
  70. acceptable. Do NOT use for cryptographic purposes.
  71. --------------------------------------------------------------------*/
  72. ub4 jenkins_hash(ub1 *k, ub4 length)
  73. {
  74. register ub4 a,b,c,len,initval;
  75. /* Set up the internal state */
  76. initval=0;
  77. len = length;
  78. a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
  79. c = initval; /* the previous hash value */
  80. length++;
  81. /*---------------------------------------- handle most of the key */
  82. while (len >= 12)
  83. {
  84. a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
  85. b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
  86. c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
  87. mix(a,b,c);
  88. k += 12; len -= 12;
  89. }
  90. /*------------------------------------- handle the last 11 bytes */
  91. c += length;
  92. switch(len) /* all the case statements fall through */
  93. {
  94. case 11: c+=((ub4)k[10]<<24);
  95. case 10: c+=((ub4)k[9]<<16);
  96. case 9 : c+=((ub4)k[8]<<8);
  97. /* the first byte of c is reserved for the length */
  98. case 8 : b+=((ub4)k[7]<<24);
  99. case 7 : b+=((ub4)k[6]<<16);
  100. case 6 : b+=((ub4)k[5]<<8);
  101. case 5 : b+=k[4];
  102. case 4 : a+=((ub4)k[3]<<24);
  103. case 3 : a+=((ub4)k[2]<<16);
  104. case 2 : a+=((ub4)k[1]<<8);
  105. case 1 : a+=k[0];
  106. /* case 0: nothing left to add */
  107. }
  108. mix(a,b,c);
  109. /*-------------------------------------------- report the result */
  110. return (c);
  111. }
  112. /* ================================================================ */
  113. unsigned long hash(char const *sym)
  114. {
  115. ub4 hashval;
  116. hashval=jenkins_hash((ub1*)sym,(ub4)strlen(sym));
  117. return(hashval);
  118. }
  119. struct sym_table *retrieve_sym(char const *sym, struct sym_table_head *hashtab)
  120. {
  121. if (sym == NULL) return NULL;
  122. for (struct sym_table *sp = hashtab->entries[hash(sym) & (hashtab->n_bins-1)];
  123. sp != NULL;
  124. sp = sp->next)
  125. {
  126. if (strcmp(sym, sp->name) == 0)
  127. return sp;
  128. }
  129. return NULL;
  130. }
  131. /**
  132. * new_species:
  133. * Allocates a new species, initializing all values.
  134. *
  135. * In: none
  136. * Out: the newly allocated species
  137. */
  138. struct species *new_species(void)
  139. {
  140. struct species *specp = CHECKED_MALLOC_STRUCT(struct species, "species");
  141. specp->species_id=0;
  142. specp->chkpt_species_id=0;
  143. specp->eff_dat_head=NULL;
  144. specp->population=0;
  145. specp->D=0.0;
  146. specp->D_ref=0.0;
  147. specp->space_step=0.0;
  148. specp->time_step=0.0;
  149. specp->max_step_length=0.0;
  150. specp->flags=0;
  151. specp->n_deceased=0;
  152. specp->cum_lifetime=0.0;
  153. specp->region_viz_value = EXCLUDE_OBJ;
  154. specp->refl_mols = NULL;
  155. specp->transp_mols = NULL;
  156. specp->absorb_mols = NULL;
  157. specp->clamp_conc_mols = NULL;
  158. return specp;
  159. }
  160. /**
  161. * new_object:
  162. * Allocates a new object, initializing all values.
  163. *
  164. * In: none
  165. * Out: the newly allocated object
  166. */
  167. struct object *new_object(void)
  168. {
  169. struct object *objp = CHECKED_MALLOC_STRUCT(struct object, "object");
  170. objp->last_name=NULL;
  171. objp->object_type=META_OBJ;
  172. objp->contents=NULL;
  173. objp->parent=NULL;
  174. objp->next=NULL;
  175. objp->first_child=NULL;
  176. objp->last_child=NULL;
  177. objp->num_regions=0;
  178. objp->regions=NULL;
  179. objp->n_walls=0;
  180. objp->n_walls_actual=0;
  181. objp->walls=NULL;
  182. objp->wall_p=NULL;
  183. objp->n_verts=0;
  184. objp->vertices=NULL;
  185. objp->total_area=0;
  186. objp->n_tiles=0;
  187. objp->n_occupied_tiles=0;
  188. init_matrix(objp->t_matrix);
  189. return objp;
  190. }
  191. /**
  192. * new_release_pattern:
  193. * Allocates a new release pattern, initializing all values.
  194. *
  195. * In: none
  196. * Out: the newly allocated release pattern
  197. */
  198. struct release_pattern *new_release_pattern(void)
  199. {
  200. struct release_pattern *rpatp = CHECKED_MALLOC_STRUCT(struct release_pattern,
  201. "release pattern");
  202. rpatp->delay=0;
  203. rpatp->release_interval=FOREVER;
  204. rpatp->train_interval=FOREVER;
  205. rpatp->train_duration=FOREVER;
  206. rpatp->number_of_trains=1;
  207. return rpatp;
  208. }
  209. /**
  210. * new_reaction:
  211. * Allocates a new reaction, initializing all values.
  212. *
  213. * In: none
  214. * Out: the newly allocated reaction
  215. */
  216. struct rxn *new_reaction(void)
  217. {
  218. struct rxn *rxnp = CHECKED_MALLOC_STRUCT(struct rxn,
  219. "reaction");
  220. rxnp->next=NULL;
  221. rxnp->n_reactants=0;
  222. rxnp->n_pathways=0;
  223. rxnp->cum_probs=NULL;
  224. rxnp->rates=NULL;
  225. rxnp->max_fixed_p=0.0;
  226. rxnp->min_noreaction_p=0.0;
  227. rxnp->pb_factor=0.0;
  228. rxnp->product_idx=NULL;
  229. rxnp->players=NULL;
  230. rxnp->geometries=NULL;
  231. rxnp->is_complex=NULL;
  232. rxnp->n_occurred=0;
  233. rxnp->n_skipped=0;
  234. rxnp->prob_t=NULL;
  235. rxnp->pathway_head=NULL;
  236. rxnp->info=NULL;
  237. return rxnp;
  238. }
  239. /**
  240. * new_reaction_pathname:
  241. * Allocates a new reaction pathname, initializing all values.
  242. *
  243. * In: none
  244. * Out: the newly allocated reaction pathname
  245. */
  246. struct rxn_pathname *new_reaction_pathname(void)
  247. {
  248. struct rxn_pathname *rxpnp = CHECKED_MALLOC_STRUCT(struct rxn_pathname,
  249. "reaction pathname");
  250. rxpnp->path_num=-1;
  251. rxpnp->rx=NULL;
  252. rxpnp->magic=NULL;
  253. return rxpnp;
  254. }
  255. /**
  256. * new_region:
  257. * Allocates a new region, initializing all values.
  258. *
  259. * In: none
  260. * Out: the newly allocated region
  261. */
  262. struct region *new_region(void)
  263. {
  264. struct region *rp = CHECKED_MALLOC_STRUCT(struct region, "region");
  265. rp->region_last_name=NULL;
  266. rp->parent=NULL;
  267. rp->element_list_head=NULL;
  268. rp->membership=NULL;
  269. rp->eff_dat_head=NULL;
  270. rp->surf_class=NULL;
  271. rp->region_viz_value=EXCLUDE_OBJ;
  272. rp->bbox=NULL;
  273. rp->area=0.0;
  274. rp->flags=0;
  275. rp->manifold_flag=MANIFOLD_UNCHECKED;
  276. rp->boundaries = NULL;
  277. rp->region_has_all_elements = 0;
  278. return rp;
  279. }
  280. /**
  281. * new_region:
  282. * Allocates a new file stream, initializing all values.
  283. *
  284. * In: none
  285. * Out: the newly allocated file stream
  286. */
  287. struct file_stream *new_filestream(void)
  288. {
  289. struct file_stream *filep = CHECKED_MALLOC_STRUCT(struct file_stream,
  290. "file stream");
  291. filep->name=NULL;
  292. filep->stream=NULL;
  293. return filep;
  294. }
  295. /**
  296. * resize_symtab:
  297. * Resize the symbol table, rehashing all values.
  298. *
  299. * In: hashtab: the symbol table
  300. * size: new size for hash table
  301. * Out: symbol table might be resized
  302. */
  303. static int resize_symtab(struct sym_table_head *hashtab, int size)
  304. {
  305. struct sym_table **entries = hashtab->entries;
  306. int n_bins = hashtab->n_bins;
  307. /* Round up to a power of two */
  308. size |= (size >> 1);
  309. size |= (size >> 2);
  310. size |= (size >> 4);
  311. size |= (size >> 8);
  312. size |= (size >> 16);
  313. ++ size;
  314. if (size > (1 << 28))
  315. size = (1 << 28);
  316. hashtab->entries = CHECKED_MALLOC_ARRAY(struct sym_table *, size, "symbol table");
  317. if (hashtab->entries == NULL)
  318. {
  319. /* XXX: Warning message? */
  320. hashtab->entries = entries;
  321. return 1;
  322. }
  323. memset(hashtab->entries, 0, size*sizeof(struct sym_table *));
  324. hashtab->n_bins = size;
  325. for (int i=0; i<n_bins; ++ i)
  326. {
  327. while (entries[i] != NULL)
  328. {
  329. struct sym_table *entry = entries[i];
  330. entries[i] = entries[i]->next;
  331. unsigned int hashval = hash(entry->name) & (size - 1);
  332. entry->next = hashtab->entries[hashval];
  333. hashtab->entries[hashval] = entry;
  334. }
  335. }
  336. free(entries);
  337. return 0;
  338. }
  339. /**
  340. * maybe_grow_symtab:
  341. * Possibly grow the symbol table.
  342. *
  343. * In: hashtab: the symbol table
  344. * Out: symbol table might be resized
  345. */
  346. static void maybe_grow_symtab(struct sym_table_head *hashtab)
  347. {
  348. if (hashtab->n_entries * 3 >= hashtab->n_bins)
  349. resize_symtab(hashtab, hashtab->n_bins * 2);
  350. }
  351. /** Stores symbol in the symbol table.
  352. Initializes value field of the symbol structure to the default value.
  353. Returns: entry in the symbol table if successfully stored,
  354. NULL - otherwise.
  355. */
  356. struct sym_table *store_sym(char const *sym,
  357. enum symbol_type_t sym_type,
  358. struct sym_table_head *hashtab,
  359. void *data)
  360. {
  361. struct sym_table *sp;
  362. unsigned hashval;
  363. void *vp = NULL;
  364. double *fp;
  365. unsigned rawhash;
  366. /* try to find sym in table */
  367. if ((sp = retrieve_sym(sym, hashtab)) == NULL)
  368. {
  369. maybe_grow_symtab(hashtab);
  370. ++ hashtab->n_entries;
  371. /* sym not found */
  372. sp = CHECKED_MALLOC_STRUCT(struct sym_table, "sym table entry");
  373. #ifdef KELP
  374. sp->ref_count=1;
  375. sp->keep_alive=0;
  376. #endif
  377. sp->name = CHECKED_STRDUP(sym, "symbol name");
  378. sp->sym_type=sym_type;
  379. rawhash = hash(sym);
  380. hashval = rawhash & (hashtab->n_bins - 1);
  381. sp->next=hashtab->entries[hashval];
  382. hashtab->entries[hashval]=sp;
  383. switch (sym_type) {
  384. case DBL:
  385. if (data == NULL)
  386. {
  387. vp = CHECKED_MALLOC_STRUCT(double, "sym table value");
  388. fp = (double *)vp;
  389. *fp = 0.0;
  390. }
  391. else
  392. vp = data;
  393. break;
  394. case STR:
  395. sp->value=data;
  396. return(sp);
  397. case ARRAY:
  398. sp->value=data;
  399. return(sp);
  400. case MOL:
  401. if (data == NULL) vp = new_species();
  402. else vp = data;
  403. ((struct species *) vp)->sym = sp;
  404. ((struct species *) vp)->hashval = rawhash;
  405. break;
  406. case OBJ:
  407. if (data == NULL) vp = new_object();
  408. else vp = data;
  409. ((struct object *) vp)->sym = sp;
  410. break;
  411. case RPAT:
  412. if (data == NULL) vp = new_release_pattern();
  413. else vp = data;
  414. ((struct release_pattern *) vp)->sym = sp;
  415. break;
  416. case RX:
  417. if (data == NULL) vp = new_reaction();
  418. else vp = data;
  419. ((struct rxn *) vp)->sym = sp;
  420. break;
  421. case RXPN:
  422. if (data == NULL) vp = new_reaction_pathname();
  423. else vp = data;
  424. ((struct rxn_pathname *) vp)->sym = sp;
  425. ((struct rxn_pathname *) vp)->hashval = rawhash;
  426. break;
  427. case REG:
  428. if (data == NULL) vp = new_region();
  429. else vp = data;
  430. ((struct region *) vp)->sym = sp;
  431. ((struct region *) vp)->hashval = rawhash;
  432. break;
  433. case FSTRM:
  434. if (data == NULL) vp = new_filestream();
  435. else vp = data;
  436. break;
  437. case TMP:
  438. case VIZ_CHILD:
  439. sp->value = data;
  440. return sp;
  441. default:
  442. mcell_internal_error("unknown symbol type in symbol table (%d)", sym_type);
  443. break;
  444. }
  445. sp->value=vp;
  446. }
  447. return sp;
  448. }
  449. /**
  450. * init_symtab:
  451. * Create a new symbol table.
  452. *
  453. * In: size: initial number of entries in the table
  454. * Out: symbol table
  455. */
  456. struct sym_table_head *init_symtab(int size)
  457. {
  458. /* Round up to a power of two */
  459. size |= (size >> 1);
  460. size |= (size >> 2);
  461. size |= (size >> 4);
  462. size |= (size >> 8);
  463. size |= (size >> 16);
  464. ++ size;
  465. if (size > (1 << 28))
  466. size = (1 << 28);
  467. /* Allocate the table and zero-initialize it. */
  468. struct sym_table_head *symtab_head;
  469. symtab_head = CHECKED_MALLOC_STRUCT(struct sym_table_head, "symbol table");
  470. symtab_head->entries = CHECKED_MALLOC_ARRAY(struct sym_table *, size, "symbol table");
  471. memset(symtab_head->entries, 0, sizeof(struct sym_table *) * size);
  472. symtab_head->n_entries = 0;
  473. symtab_head->n_bins = size;
  474. return symtab_head;
  475. }
  476. /**
  477. * destroy_symtab:
  478. * Destroy and deallocate a symbol table.
  479. *
  480. * In: tab: table to destroy
  481. * Out: table is deallocated
  482. */
  483. void destroy_symtab(struct sym_table_head *tab)
  484. {
  485. for (int i=0; i<tab->n_bins; ++i)
  486. {
  487. struct sym_table *next;
  488. for (struct sym_table *sym = tab->entries[i];
  489. sym != NULL;
  490. sym = next)
  491. {
  492. next = sym->next;
  493. free(sym);
  494. }
  495. }
  496. free(tab->entries);
  497. free(tab);
  498. }