opcua_namespace.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. #include "opcua_namespace.h"
  2. #include <string.h>
  3. #include <stdio.h>
  4. /* The basic data structure is a hash-map of UA_Node objects.
  5. Entry lookup via Algorithm D from Knuth's TAOCP (no linked lists here).
  6. Table of primes and mod-functions are from libiberty (licensed under LGPL) */
  7. struct prime_ent {
  8. hash_t prime;
  9. hash_t inv;
  10. hash_t inv_m2; /* inverse of prime-2 */
  11. hash_t shift;
  12. };
  13. static struct prime_ent const prime_tab[] = {
  14. { 7, 0x24924925, 0x9999999b, 2 },
  15. { 13, 0x3b13b13c, 0x745d1747, 3 },
  16. { 31, 0x08421085, 0x1a7b9612, 4 },
  17. { 61, 0x0c9714fc, 0x15b1e5f8, 5 },
  18. { 127, 0x02040811, 0x0624dd30, 6 },
  19. { 251, 0x05197f7e, 0x073260a5, 7 },
  20. { 509, 0x01824366, 0x02864fc8, 8 },
  21. { 1021, 0x00c0906d, 0x014191f7, 9 },
  22. { 2039, 0x0121456f, 0x0161e69e, 10 },
  23. { 4093, 0x00300902, 0x00501908, 11 },
  24. { 8191, 0x00080041, 0x00180241, 12 },
  25. { 16381, 0x000c0091, 0x00140191, 13 },
  26. { 32749, 0x002605a5, 0x002a06e6, 14 },
  27. { 65521, 0x000f00e2, 0x00110122, 15 },
  28. { 131071, 0x00008001, 0x00018003, 16 },
  29. { 262139, 0x00014002, 0x0001c004, 17 },
  30. { 524287, 0x00002001, 0x00006001, 18 },
  31. { 1048573, 0x00003001, 0x00005001, 19 },
  32. { 2097143, 0x00004801, 0x00005801, 20 },
  33. { 4194301, 0x00000c01, 0x00001401, 21 },
  34. { 8388593, 0x00001e01, 0x00002201, 22 },
  35. { 16777213, 0x00000301, 0x00000501, 23 },
  36. { 33554393, 0x00001381, 0x00001481, 24 },
  37. { 67108859, 0x00000141, 0x000001c1, 25 },
  38. { 134217689, 0x000004e1, 0x00000521, 26 },
  39. { 268435399, 0x00000391, 0x000003b1, 27 },
  40. { 536870909, 0x00000019, 0x00000029, 28 },
  41. { 1073741789, 0x0000008d, 0x00000095, 29 },
  42. { 2147483647, 0x00000003, 0x00000007, 30 },
  43. /* Avoid "decimal constant so large it is unsigned" for 4294967291. */
  44. { 0xfffffffb, 0x00000006, 0x00000008, 31 }
  45. };
  46. UA_Int32 create_ns(namespace **result, uint32_t size) {
  47. namespace *ns = UA_NULL;
  48. uint32_t sizePrimeIndex = higher_prime_index(size);
  49. size = prime_tab[sizePrimeIndex].prime;
  50. if (UA_alloc((void **)&ns, sizeof(namespace)) != UA_SUCCESS) return UA_ERR_NO_MEMORY;
  51. if (UA_alloc((void **)&(ns->entries), sizeof(void *)*size) != UA_SUCCESS) {
  52. UA_free(ns);
  53. return UA_ERR_NO_MEMORY;
  54. }
  55. for (uint32_t i=0; i<size;i++)
  56. ns->entries[i] = UA_NULL;
  57. ns->size = size;
  58. ns->count = 0;
  59. ns->sizePrimeIndex = sizePrimeIndex;
  60. *result = ns;
  61. return UA_SUCCESS;
  62. }
  63. void empty_ns(namespace *ns) {
  64. uint32_t size = ns->size;
  65. UA_Node **entries = ns->entries;
  66. for (uint32_t i = 0; i < size; i++) {
  67. if (entries[i] != UA_NULL) {
  68. switch(entries[i]->nodeClass) {
  69. case UA_NODECLASS_OBJECT:
  70. // UA_ObjectNode_delete((UA_ObjectNode *) entries[i]);
  71. break;
  72. case UA_NODECLASS_VARIABLE:
  73. // UA_VariableNode_delete((UA_VariableNode *) entries[i]);
  74. break;
  75. case UA_NODECLASS_METHOD:
  76. // UA_MethodNode_delete((UA_MethodNode *) entries[i]);
  77. break;
  78. case UA_NODECLASS_OBJECTTYPE:
  79. // UA_ObjectTypeNode_delete((UA_ObjectTypeNode *) entries[i]);
  80. break;
  81. case UA_NODECLASS_VARIABLETYPE:
  82. // UA_VariableTypeNode_delete((UA_VariableTypeNode *) entries[i]);
  83. break;
  84. case UA_NODECLASS_REFERENCETYPE:
  85. // UA_ReferenceTypeNode_delete((UA_ReferenceTypeNode *) entries[i]);
  86. break;
  87. case UA_NODECLASS_DATATYPE:
  88. // UA_DataTypeNode_delete((UA_DataTypeNode *) entries[i]);
  89. break;
  90. case UA_NODECLASS_VIEW:
  91. // UA_ViewNode_delete((UA_ViewNode *) entries[i]);
  92. break;
  93. default:
  94. break; // Unspecified nodes are not permitted.
  95. }
  96. }
  97. }
  98. /* Downsize the table. */
  99. if (size > 1024*1024 / sizeof (void *)) {
  100. int nindex = higher_prime_index (1024 / sizeof (void *));
  101. int nsize = prime_tab[nindex].prime;
  102. UA_free(ns->entries);
  103. UA_alloc((void **)&(ns->entries), sizeof(void *)*nsize); //FIXME: Check if memory was available
  104. ns->size = nsize;
  105. ns->sizePrimeIndex = nindex;
  106. ns->count = 0;
  107. }
  108. else {
  109. memset(*(ns->entries), 0, size * sizeof(void *));
  110. ns->count = 0;
  111. }
  112. }
  113. /* This function frees all memory allocated for a namespace */
  114. void delete_ns (namespace *ns) {
  115. uint32_t size = ns->size;
  116. UA_Node **entries = ns->entries;
  117. for (uint32_t i = 0; i < size; i++) {
  118. if (entries[i] != UA_NULL) {
  119. switch(entries[i]->nodeClass) {
  120. case UA_NODECLASS_OBJECT:
  121. // UA_ObjectNode_delete((UA_ObjectNode *) entries[i]);
  122. break;
  123. case UA_NODECLASS_VARIABLE:
  124. // UA_VariableNode_delete((UA_VariableNode *) entries[i]);
  125. break;
  126. case UA_NODECLASS_METHOD:
  127. // UA_MethodNode_delete((UA_MethodNode *) entries[i]);
  128. break;
  129. case UA_NODECLASS_OBJECTTYPE:
  130. // UA_ObjectTypeNode_delete((UA_ObjectTypeNode *) entries[i]);
  131. break;
  132. case UA_NODECLASS_VARIABLETYPE:
  133. // UA_VariableTypeNode_delete((UA_VariableTypeNode *) entries[i]);
  134. break;
  135. case UA_NODECLASS_REFERENCETYPE:
  136. // UA_ReferenceTypeNode_delete((UA_ReferenceTypeNode *) entries[i]);
  137. break;
  138. case UA_NODECLASS_DATATYPE:
  139. // UA_DataTypeNode_delete((UA_DataTypeNode *) entries[i]);
  140. break;
  141. case UA_NODECLASS_VIEW:
  142. // UA_ViewNode_delete((UA_ViewNode *) entries[i]);
  143. break;
  144. default:
  145. break; // Unspecified nodes are not permitted.
  146. }
  147. }
  148. }
  149. UA_free(entries);
  150. UA_free(ns);
  151. }
  152. UA_Int32 insert(namespace *ns, UA_Node *node) {
  153. if((float)ns->count/(float)ns->size < 0.75) {
  154. if(expand(ns) != UA_SUCCESS)
  155. return UA_ERROR;
  156. }
  157. hash_t h = hash(&(node->nodeId));
  158. UA_Node **slot = find_empty_slot(ns, h);
  159. *slot = node;
  160. return UA_SUCCESS;
  161. }
  162. UA_Int32 find(namespace *ns, UA_Node **result, UA_NodeId *nodeid) {
  163. UA_Node **slot = UA_NULL;
  164. if(find_slot(ns, slot, nodeid) == UA_SUCCESS) {
  165. *result = *slot;
  166. return UA_SUCCESS;
  167. }
  168. return UA_ERROR;
  169. }
  170. void delete(namespace *ns, UA_NodeId *nodeid) {
  171. UA_Node **slot = UA_NULL;
  172. if (find_slot(ns, slot, nodeid) != UA_SUCCESS)
  173. return;
  174. UA_Node *node = *slot;
  175. *slot = UA_NULL;
  176. switch(node->nodeClass) {
  177. case UA_NODECLASS_OBJECT:
  178. // UA_ObjectNode_delete((UA_ObjectNode *) node);
  179. break;
  180. case UA_NODECLASS_VARIABLE:
  181. // UA_VariableNode_delete((UA_VariableNode *) node);
  182. break;
  183. case UA_NODECLASS_METHOD:
  184. // UA_MethodNode_delete((UA_MethodNode *) node);
  185. break;
  186. case UA_NODECLASS_OBJECTTYPE:
  187. // UA_ObjectTypeNode_delete((UA_ObjectTypeNode *) node);
  188. break;
  189. case UA_NODECLASS_VARIABLETYPE:
  190. // UA_VariableTypeNode_delete((UA_VariableTypeNode *) node);
  191. break;
  192. case UA_NODECLASS_REFERENCETYPE:
  193. // UA_ReferenceTypeNode_delete((UA_ReferenceTypeNode *) node);
  194. break;
  195. case UA_NODECLASS_DATATYPE:
  196. // UA_DataTypeNode_delete((UA_DataTypeNode *) node);
  197. break;
  198. case UA_NODECLASS_VIEW:
  199. // UA_ViewNode_delete((UA_ViewNode *) node);
  200. break;
  201. default:
  202. break; // Unspecified nodes are not permitted.
  203. }
  204. }
  205. /* Hashing inspired by code from from http://www.azillionmonkeys.com/qed/hash.html, licensed under the LGPL 2.1 */
  206. #undef get16bits
  207. #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
  208. #define get16bits(d) (*((const uint16_t *) (d)))
  209. #endif
  210. #if !defined (get16bits)
  211. #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) +(uint32_t)(((const uint8_t *)(d))[0]) )
  212. #endif
  213. static hash_t hash_string (const UA_Byte * data, UA_Int32 len) {
  214. hash_t hash = len;
  215. hash_t tmp;
  216. int rem;
  217. if (len <= 0 || data == UA_NULL) return 0;
  218. rem = len & 3;
  219. len >>= 2;
  220. /* Main loop */
  221. for (;len > 0; len--) {
  222. hash += get16bits (data);
  223. tmp = (get16bits (data+2) << 11) ^ hash;
  224. hash = (hash << 16) ^ tmp;
  225. data += 2*sizeof (uint16_t);
  226. hash += hash >> 11;
  227. }
  228. /* Handle end cases */
  229. switch (rem) {
  230. case 3: hash += get16bits (data);
  231. hash ^= hash << 16;
  232. hash ^= ((signed char)data[sizeof (uint16_t)]) << 18;
  233. hash += hash >> 11;
  234. break;
  235. case 2: hash += get16bits (data);
  236. hash ^= hash << 11;
  237. hash += hash >> 17;
  238. break;
  239. case 1: hash += (signed char)*data;
  240. hash ^= hash << 10;
  241. hash += hash >> 1;
  242. }
  243. /* Force "avalanching" of final 127 bits */
  244. hash ^= hash << 3;
  245. hash += hash >> 5;
  246. hash ^= hash << 4;
  247. hash += hash >> 17;
  248. hash ^= hash << 25;
  249. hash += hash >> 6;
  250. return hash;
  251. }
  252. static hash_t hash(const UA_NodeId *n) {
  253. switch (n->encodingByte) {
  254. case UA_NODEIDTYPE_TWOBYTE:
  255. case UA_NODEIDTYPE_FOURBYTE:
  256. case UA_NODEIDTYPE_NUMERIC:
  257. return n->identifier.numeric;
  258. case UA_NODEIDTYPE_STRING:
  259. return hash_string(n->identifier.string.data, n->identifier.string.length);
  260. case UA_NODEIDTYPE_GUID:
  261. return hash_string((UA_Byte*) &(n->identifier.guid), sizeof(UA_Guid));
  262. case UA_NODEIDTYPE_BYTESTRING:
  263. return hash_string((UA_Byte*) n->identifier.byteString.data, n->identifier.byteString.length);
  264. default:
  265. // Not permitted
  266. return 0;
  267. }
  268. }
  269. /* The following function returns an index into the above table of the nearest prime number which is greater than N, and near a power of two. */
  270. static unsigned int higher_prime_index (unsigned long n) {
  271. unsigned int low = 0;
  272. unsigned int high = sizeof(prime_tab) / sizeof(prime_tab[0]);
  273. while (low != high) {
  274. unsigned int mid = low + (high - low) / 2;
  275. if (n > prime_tab[mid].prime)
  276. low = mid + 1;
  277. else
  278. high = mid;
  279. }
  280. // Fixme: If we've run out of primes, abort.
  281. /* if (n > prime_tab[low].prime) */
  282. /* abort (); */
  283. return low;
  284. }
  285. /* Return X % Y. */
  286. static inline hash_t mod_1 (hash_t x, hash_t y, hash_t inv, int shift) {
  287. /* The multiplicative inverses computed above are for 32-bit types, and requires that we are able to compute a highpart multiply. */
  288. #ifdef UNSIGNED_64BIT_TYPE
  289. __extension__ typedef UNSIGNED_64BIT_TYPE ull;
  290. if (sizeof (hash_t) * CHAR_BIT <= 32) {
  291. hash_t t1, t2, t3, t4, q, r;
  292. t1 = ((ull)x * inv) >> 32;
  293. t2 = x - t1;
  294. t3 = t2 >> 1;
  295. t4 = t1 + t3;
  296. q = t4 >> shift;
  297. r = x - (q * y);
  298. return r;
  299. }
  300. #endif
  301. return x % y; /* Otherwise just use the native division routines. */
  302. }
  303. static inline hash_t mod (hash_t h, const namespace *ns) {
  304. const struct prime_ent *p = &prime_tab[ns->sizePrimeIndex];
  305. return mod_1 (h, p->prime, p->inv, p->shift);
  306. }
  307. static inline hash_t mod_m2 (hash_t h, const namespace *ns) {
  308. const struct prime_ent *p = &prime_tab[ns->sizePrimeIndex];
  309. return 1 + mod_1 (h, p->prime - 2, p->inv_m2, p->shift);
  310. }
  311. static UA_Int32 find_slot (const namespace *ns, UA_Node **slot, UA_NodeId *nodeid) {
  312. hash_t h = hash(nodeid);
  313. hash_t index, hash2;
  314. uint32_t size;
  315. UA_Node *entry;
  316. size = ns->size;
  317. index = mod(h, ns);
  318. entry = ns->entries[index];
  319. if (entry == UA_NULL)
  320. return UA_ERROR;
  321. if (UA_NodeId_compare(&(entry->nodeId), nodeid)) {
  322. *slot = ns->entries[index];
  323. return UA_SUCCESS;
  324. }
  325. hash2 = mod_m2(h, ns);
  326. for (;;) {
  327. index += hash2;
  328. if (index >= size)
  329. index -= size;
  330. entry = ns->entries[index];
  331. if (entry == UA_NULL)
  332. return UA_ERROR;
  333. if (UA_NodeId_compare(&(entry->nodeId), nodeid)) {
  334. slot = &(ns->entries[index]);
  335. return UA_SUCCESS;
  336. }
  337. }
  338. }
  339. /* Always returns an empty slot. This is inevitable if the entries are not
  340. completely full. */
  341. static UA_Node ** find_empty_slot(const namespace *ns, hash_t h) {
  342. hash_t index = mod(h, ns);
  343. uint32_t size = ns->size;
  344. UA_Node **slot = ns->entries + index;
  345. if (*slot == UA_NULL)
  346. return slot;
  347. hash_t hash2 = mod_m2 (h, ns);
  348. for (;;) {
  349. index += hash2;
  350. if (index >= size)
  351. index -= size;
  352. slot = ns->entries + index;
  353. if (*slot == UA_NULL)
  354. return slot;
  355. }
  356. }
  357. /* The following function changes size of memory allocated for the
  358. entries and repeatedly inserts the table elements. The occupancy
  359. of the table after the call will be about 50%. Naturally the hash
  360. table must already exist. Remember also that the place of the
  361. table entries is changed. If memory allocation failures are allowed,
  362. this function will return zero, indicating that the table could not be
  363. expanded. If all goes well, it will return a non-zero value. */
  364. static UA_Int32 expand (namespace *ns) {
  365. UA_Node **p;
  366. UA_Node **nentries;
  367. int32_t nsize;
  368. uint32_t nindex;
  369. UA_Node **oentries = ns->entries;
  370. int32_t osize = ns->size;
  371. UA_Node **olimit = oentries + osize;
  372. int32_t count = ns->count;
  373. /* Resize only when table after removal of unused elements is either too full or too empty. */
  374. if (count * 2 > osize || (count * 8 < osize && osize > 32)) {
  375. nindex = higher_prime_index (count * 2);
  376. nsize = prime_tab[nindex].prime;
  377. }
  378. return UA_SUCCESS;
  379. if (UA_alloc((void **)nentries, sizeof(void *)*nsize) != UA_SUCCESS)
  380. return UA_ERR_NO_MEMORY;
  381. ns->entries = nentries;
  382. ns->size = nsize;
  383. ns->sizePrimeIndex = nindex;
  384. p = oentries;
  385. do {
  386. UA_Node *x = *p;
  387. if (x != UA_NULL) {
  388. UA_Node **q = find_empty_slot(ns, hash(&(x->nodeId)));
  389. *q = x;
  390. }
  391. p++;
  392. }
  393. while (p < olimit);
  394. UA_free(oentries);
  395. return UA_SUCCESS;
  396. }