PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/ncl_ncarg-6.0.0/ni/src/lib/nio/nioQuarks.c

#
C | 397 lines | 306 code | 30 blank | 61 comment | 59 complexity | b0880051d48e81d41000380e8e95f4b5 MD5 | raw file
  1. /*
  2. * $Id: nioQuarks.c,v 1.1 2009-05-15 00:49:27 dbrown Exp $
  3. */
  4. /************************************************************************
  5. * *
  6. * Copyright (C) 1992 *
  7. * University Corporation for Atmospheric Research *
  8. * All Rights Reserved *
  9. * *
  10. ************************************************************************/
  11. /*
  12. * File: Quarks.c
  13. *
  14. * Author: Jeff W. Boote
  15. * National Center for Atmospheric Research
  16. * PO 3000, Boulder, Colorado
  17. *
  18. * Date: Tue Sep 8 17:13:47 MDT 1992
  19. *
  20. * Description: This file was taken from the mit X distribution. It
  21. * has been modified to support the hlu library.
  22. */
  23. /*
  24. */
  25. /***********************************************************
  26. Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard,
  27. Massachusetts, and the Massachusetts Institute of Technology, Cambridge,
  28. Massachusetts.
  29. All Rights Reserved
  30. Permission to use, copy, modify, and distribute this software and its
  31. documentation for any purpose and without fee is hereby granted,
  32. provided that the above copyright notice appear in all copies and that
  33. both that copyright notice and this permission notice appear in
  34. supporting documentation, and that the names of Digital or MIT not be
  35. used in advertising or publicity pertaining to distribution of the
  36. software without specific, written prior permission.
  37. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  38. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  39. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  40. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  41. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  42. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  43. SOFTWARE.
  44. ******************************************************************/
  45. #define NeedFunctionPrototypes NhlNeedProto
  46. #include "niohlu.h"
  47. #include "nioNresDB.h"
  48. /* Not cost effective, at least for vanilla MIT clients */
  49. /* #define PERMQ */
  50. typedef unsigned long Entry;
  51. #ifdef PERMQ
  52. typedef unsigned char Bits;
  53. #endif
  54. static NrmQuark nextQuark = 1; /* next available quark number */
  55. static unsigned long quarkMask = 0;
  56. static Entry zero = 0;
  57. static Entry *quarkTable = &zero; /* crock */
  58. static unsigned long quarkRehash;
  59. static NrmString **stringTable = NULL;
  60. #ifdef PERMQ
  61. static Bits **permTable = NULL;
  62. #endif
  63. static NrmQuark nextUniq = -1; /* next quark from NrmUniqueQuark */
  64. #define QUANTUMSHIFT 8
  65. #define QUANTUMMASK ((1 << QUANTUMSHIFT) - 1)
  66. #define CHUNKPER 8
  67. #define CHUNKMASK ((CHUNKPER << QUANTUMSHIFT) - 1)
  68. #define LARGEQUARK ((Entry)0x80000000L)
  69. #define QUARKSHIFT 18
  70. #define QUARKMASK ((LARGEQUARK - 1) >> QUARKSHIFT)
  71. #define SIGMASK ((1L << QUARKSHIFT) - 1)
  72. #define STRQUANTSIZE (sizeof(NrmString) * (QUANTUMMASK + 1))
  73. #ifdef PERMQ
  74. #define QUANTSIZE (STRQUANTSIZE + \
  75. (sizeof(Bits) * ((QUANTUMMASK + 1) >> 3))
  76. #else
  77. #define QUANTSIZE STRQUANTSIZE
  78. #endif
  79. #define HASH(sig) ((sig) & quarkMask)
  80. #define REHASHVAL(sig) ((((sig) % quarkRehash) + 2) | 1)
  81. #define REHASH(idx,rehash) ((idx + rehash) & quarkMask)
  82. #define NAME(q) stringTable[(q) >> QUANTUMSHIFT][(q) & QUANTUMMASK]
  83. #ifdef PERMQ
  84. #define BYTEREF(q) permTable[(q) >> QUANTUMSHIFT][((q) & QUANTUMMASK) >> 3]
  85. #define ISPERM(q) (BYTEREF(q) & (1 << ((q) & 7)))
  86. #define SETPERM(q) BYTEREF(q) |= (1 << ((q) & 7))
  87. #define CLEARPERM(q) BYTEREF(q) &= ~(1 << ((q) & 7))
  88. #endif
  89. /* Permanent memory allocation */
  90. #define WALIGN sizeof(unsigned long)
  91. #define DALIGN sizeof(double)
  92. #define NEVERFREETABLESIZE ((8192-12) & ~(DALIGN-1))
  93. static char *neverFreeTable = NULL;
  94. static int neverFreeTableSize = 0;
  95. static char *permalloc(length)
  96. register unsigned int length;
  97. {
  98. char *ret;
  99. if (neverFreeTableSize < length) {
  100. if (length >= NEVERFREETABLESIZE)
  101. return (char *)NhlMalloc(length);
  102. ret = (char *)NhlMalloc(NEVERFREETABLESIZE);
  103. if (!ret)
  104. return (char *) NULL;
  105. neverFreeTableSize = NEVERFREETABLESIZE;
  106. neverFreeTable = ret;
  107. }
  108. ret = neverFreeTable;
  109. neverFreeTable += length;
  110. neverFreeTableSize -= length;
  111. return(ret);
  112. }
  113. char *Npermalloc(length)
  114. unsigned int length;
  115. {
  116. int i;
  117. if (neverFreeTableSize && length < NEVERFREETABLESIZE) {
  118. #ifndef WORD64
  119. if ((sizeof(struct {char a; double b;}) !=
  120. (sizeof(struct {char a; unsigned long b;}) -
  121. sizeof(unsigned long) + sizeof(double))) &&
  122. !(length & (DALIGN-1)) &&
  123. ((i = (NEVERFREETABLESIZE - neverFreeTableSize) & (DALIGN-1))!=0)) {
  124. neverFreeTableSize -= DALIGN - i;
  125. neverFreeTable += DALIGN - i;
  126. } else
  127. #endif
  128. /* SUPPRESS 624 */
  129. if ((i = (NEVERFREETABLESIZE-neverFreeTableSize)&(WALIGN-1)) != 0){
  130. neverFreeTableSize -= WALIGN - i;
  131. neverFreeTable += WALIGN - i;
  132. }
  133. }
  134. return permalloc(length);
  135. }
  136. static NhlBoolean
  137. ExpandQuarkTable()
  138. {
  139. unsigned long oldmask, newmask;
  140. register char c, *s;
  141. register Entry *oldentries, *entries;
  142. register Entry entry;
  143. register int oldidx, newidx, rehash;
  144. Signature sig;
  145. NrmQuark q;
  146. oldentries = quarkTable;
  147. /* SUPPRESS 624 */
  148. if ((oldmask = quarkMask) != 0)
  149. newmask = (oldmask << 1) + 1;
  150. else {
  151. if (!stringTable) {
  152. stringTable = (NrmString **)NhlMalloc(sizeof(NrmString *) *
  153. CHUNKPER);
  154. if (!stringTable)
  155. return False;
  156. stringTable[0] = (NrmString *)NULL;
  157. }
  158. #ifdef PERMQ
  159. if (!permTable)
  160. permTable = (Bits **)NhlMalloc(sizeof(Bits *) * CHUNKPER);
  161. if (!permTable)
  162. return False;
  163. #endif
  164. stringTable[0] = (NrmString *)Npermalloc(QUANTSIZE);
  165. if (!stringTable[0])
  166. return False;
  167. #ifdef PERMQ
  168. permTable[0] = (Bits *)((char *)stringTable[0] + STRQUANTSIZE);
  169. #endif
  170. newmask = 0x1ff;
  171. }
  172. entries = (Entry *)NhlMalloc(sizeof(Entry) * (newmask + 1));
  173. if (!entries)
  174. return False;
  175. memset((char*)entries,0, sizeof(Entry) * (newmask + 1));
  176. quarkTable = entries;
  177. quarkMask = newmask;
  178. quarkRehash = quarkMask - 2;
  179. for (oldidx = 0; oldidx <= oldmask; oldidx++) {
  180. /* SUPPRESS 624 */
  181. if ((entry = oldentries[oldidx]) != 0) {
  182. if (entry & LARGEQUARK)
  183. q = entry & (LARGEQUARK-1);
  184. else
  185. q = (entry >> QUARKSHIFT) & QUARKMASK;
  186. /* SUPPRESS 624 */
  187. for (sig = 0, s = NAME(q); ((c = *s++)!=0); )
  188. sig = (sig << 1) + c;
  189. newidx = HASH(sig);
  190. if (entries[newidx]) {
  191. rehash = REHASHVAL(sig);
  192. do {
  193. newidx = REHASH(newidx, rehash);
  194. } while (entries[newidx]);
  195. }
  196. entries[newidx] = entry;
  197. }
  198. }
  199. if (oldmask)
  200. NhlFree((char *)oldentries);
  201. return True;
  202. }
  203. #if NeedFunctionPrototypes
  204. NrmQuark _NrmInternalStringToQuark(
  205. register Const char *name, register int len, register Signature sig,
  206. NhlBoolean permstring)
  207. #else
  208. NrmQuark _NrmInternalStringToQuark(name, len, sig, permstring)
  209. register NrmString name;
  210. register int len;
  211. register Signature sig;
  212. NhlBoolean permstring;
  213. #endif
  214. {
  215. register NrmQuark q;
  216. register Entry entry;
  217. register int idx, rehash;
  218. register int i;
  219. register char *s1, *s2;
  220. char *new;
  221. rehash = 0;
  222. idx = HASH(sig);
  223. /* SUPPRESS 624 */
  224. while ((entry = quarkTable[idx]) != 0) {
  225. if (entry & LARGEQUARK)
  226. q = entry & (LARGEQUARK-1);
  227. else {
  228. if ((entry - sig) & SIGMASK)
  229. goto nomatch;
  230. q = (entry >> QUARKSHIFT) & QUARKMASK;
  231. }
  232. for (i = len, s1 = (char *)name, s2 = NAME(q); --i >= 0; ) {
  233. if (*s1++ != *s2++)
  234. goto nomatch;
  235. }
  236. if (*s2) {
  237. nomatch: if (!rehash)
  238. rehash = REHASHVAL(sig);
  239. idx = REHASH(idx, rehash);
  240. continue;
  241. }
  242. #ifdef PERMQ
  243. if (permstring && !ISPERM(q)) {
  244. NhlFree(NAME(q));
  245. NAME(q) = (char *)name;
  246. SETPERM(q);
  247. }
  248. #endif
  249. return q;
  250. }
  251. if (nextUniq == nextQuark)
  252. return NrmNULLQUARK;
  253. if ((nextQuark + (nextQuark >> 2)) > quarkMask) {
  254. if (!ExpandQuarkTable())
  255. return NrmNULLQUARK;
  256. return _NrmInternalStringToQuark(name, len, sig, permstring);
  257. }
  258. q = nextQuark;
  259. if (!(q & QUANTUMMASK)) {
  260. if (!(q & CHUNKMASK)) {
  261. new = (char *)NhlRealloc((char *)stringTable,
  262. sizeof(NrmString *) *
  263. ((q >> QUANTUMSHIFT) + CHUNKPER));
  264. if (!new)
  265. return NrmNULLQUARK;
  266. stringTable = (NrmString **)new;
  267. #ifdef PERMQ
  268. if (!(new = NhlRealloc((char *)permTable,
  269. sizeof(Bits *) *
  270. ((q >> QUANTUMSHIFT) + CHUNKPER))))
  271. return NrmNULLQUARK;
  272. permTable = (Bits **)new;
  273. #endif
  274. }
  275. new = Npermalloc(QUANTSIZE);
  276. if (!new)
  277. return NrmNULLQUARK;
  278. stringTable[q >> QUANTUMSHIFT] = (NrmString *)new;
  279. #ifdef PERMQ
  280. permTable[q >> QUANTUMSHIFT] = (Bits *)(new + STRQUANTSIZE);
  281. #endif
  282. }
  283. if (!permstring) {
  284. s2 = (char *)name;
  285. #ifdef PERMQ
  286. name = NhlMalloc(len+1);
  287. #else
  288. name = permalloc(len+1);
  289. #endif
  290. if (!name)
  291. return NrmNULLQUARK;
  292. for (i = len, s1 = (char *)name; --i >= 0; )
  293. *s1++ = *s2++;
  294. *s1++ = '\0';
  295. #ifdef PERMQ
  296. CLEARPERM(q);
  297. }
  298. else {
  299. SETPERM(q);
  300. #endif
  301. }
  302. NAME(q) = (char *)name;
  303. if (q <= QUARKMASK)
  304. entry = (q << QUARKSHIFT) | (sig & SIGMASK);
  305. else
  306. entry = q | LARGEQUARK;
  307. quarkTable[idx] = entry;
  308. nextQuark++;
  309. return q;
  310. }
  311. #if NeedFunctionPrototypes
  312. NrmQuark NrmStringToQuark(
  313. Const char *name)
  314. #else
  315. NrmQuark NrmStringToQuark(name)
  316. NrmString name;
  317. #endif
  318. {
  319. register char c, *tname;
  320. register Signature sig = 0;
  321. if (!name)
  322. return (NrmNULLQUARK);
  323. /* SUPPRESS 624 */
  324. for (tname = (char *)name; ((c = *tname++)!=0); )
  325. sig = (sig << 1) + c;
  326. return _NrmInternalStringToQuark(name, tname-(char *)name-1, sig, False);
  327. }
  328. #if NeedFunctionPrototypes
  329. NrmQuark NrmPermStringToQuark(
  330. Const char *name)
  331. #else
  332. NrmQuark NrmPermStringToQuark(name)
  333. NrmString name;
  334. #endif
  335. {
  336. register char c, *tname;
  337. register Signature sig = 0;
  338. if (!name)
  339. return (NrmNULLQUARK);
  340. /* SUPPRESS 624 */
  341. for (tname = (char *)name; ((c = *tname++)!=0); )
  342. sig = (sig << 1) + c;
  343. return _NrmInternalStringToQuark(name, tname-(char *)name-1, sig, True);
  344. }
  345. NrmQuark NrmUniqueQuark()
  346. {
  347. if (nextUniq == nextQuark)
  348. return NrmNULLQUARK;
  349. return nextUniq--;
  350. }
  351. NrmString NrmQuarkToString(quark)
  352. register NrmQuark quark;
  353. {
  354. if (quark <= 0 || quark >= nextQuark)
  355. return NrmNULLSTRING;
  356. #ifdef PERMQ
  357. /* We have to mark the quark as permanent, since the caller might hold
  358. * onto the string pointer forver.
  359. */
  360. SETPERM(quark);
  361. #endif
  362. return NAME(quark);
  363. }