db.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. // $Id: db.c,v 1.2 2004/09/23 14:43:06 MouseJstr Exp $
  2. // #define MALLOC_DBN
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "db.h"
  7. #include "mmo.h"
  8. #include "utils.h"
  9. #ifdef MEMWATCH
  10. #include "memwatch.h"
  11. #endif
  12. #define ROOT_SIZE 4096
  13. #ifdef MALLOC_DBN
  14. static struct dbn *dbn_root[512], *dbn_free;
  15. static int dbn_root_rest=0,dbn_root_num=0;
  16. static void * malloc_dbn(void)
  17. {
  18. struct dbn* ret;
  19. if(dbn_free==NULL){
  20. if(dbn_root_rest<=0){
  21. CREATE(dbn_root[dbn_root_num], struct dbn, ROOT_SIZE);
  22. dbn_root_rest=ROOT_SIZE;
  23. dbn_root_num++;
  24. }
  25. return &(dbn_root[dbn_root_num-1][--dbn_root_rest]);
  26. }
  27. ret=dbn_free;
  28. dbn_free = dbn_free->parent;
  29. return ret;
  30. }
  31. static void free_dbn(struct dbn* add_dbn)
  32. {
  33. add_dbn->parent = dbn_free;
  34. dbn_free = add_dbn;
  35. }
  36. #endif
  37. static int strdb_cmp(struct dbt* table,void* a,void* b)
  38. {
  39. if(table->maxlen)
  40. return strncmp(a,b,table->maxlen);
  41. return strcmp(a,b);
  42. }
  43. static unsigned int strdb_hash(struct dbt* table,void* a)
  44. {
  45. int i;
  46. unsigned int h;
  47. unsigned char *p=a;
  48. i=table->maxlen;
  49. if(i==0) i=0x7fffffff;
  50. for(h=0;*p && --i>=0;){
  51. h=(h*33 + *p++) ^ (h>>24);
  52. }
  53. return h;
  54. }
  55. struct dbt* strdb_init(int maxlen)
  56. {
  57. int i;
  58. struct dbt* table;
  59. CREATE(table, struct dbt, 1);
  60. table->cmp=strdb_cmp;
  61. table->hash=strdb_hash;
  62. table->maxlen=maxlen;
  63. for(i=0;i<HASH_SIZE;i++)
  64. table->ht[i]=NULL;
  65. return table;
  66. }
  67. static int numdb_cmp(struct dbt* table,void* a,void* b)
  68. {
  69. int ia,ib;
  70. ia=(int)a;
  71. ib=(int)b;
  72. if((ia^ib) & 0x80000000)
  73. return ia<0 ? -1 : 1;
  74. return ia-ib;
  75. }
  76. static unsigned int numdb_hash(struct dbt* table,void* a)
  77. {
  78. return (unsigned int)a;
  79. }
  80. struct dbt* numdb_init(void)
  81. {
  82. int i;
  83. struct dbt* table;
  84. CREATE(table, struct dbt, 1);
  85. table->cmp=numdb_cmp;
  86. table->hash=numdb_hash;
  87. table->maxlen=sizeof(int);
  88. for(i=0;i<HASH_SIZE;i++)
  89. table->ht[i]=NULL;
  90. return table;
  91. }
  92. void* db_search(struct dbt *table,void* key)
  93. {
  94. struct dbn *p;
  95. for(p=table->ht[table->hash(table,key) % HASH_SIZE];p;){
  96. int c=table->cmp(table,key,p->key);
  97. if(c==0)
  98. return p->data;
  99. if(c<0)
  100. p=p->left;
  101. else
  102. p=p->right;
  103. }
  104. return NULL;
  105. }
  106. void * db_search2(struct dbt *table, const char *key)
  107. {
  108. int i,sp;
  109. struct dbn *p,*pn,*stack[64];
  110. int slen = strlen(key);
  111. for(i=0;i<HASH_SIZE;i++){
  112. if((p=table->ht[i])==NULL)
  113. continue;
  114. sp=0;
  115. while(1){
  116. if (strnicmp(key, p->key, slen) == 0)
  117. return p->data;
  118. if((pn=p->left)!=NULL){
  119. if(p->right){
  120. stack[sp++]=p->right;
  121. }
  122. p=pn;
  123. } else {
  124. if(p->right){
  125. p=p->right;
  126. } else {
  127. if(sp==0)
  128. break;
  129. p=stack[--sp];
  130. }
  131. }
  132. }
  133. }
  134. return 0;
  135. }
  136. static void db_rotate_left(struct dbn *p,struct dbn **root)
  137. {
  138. struct dbn * y = p->right;
  139. p->right = y->left;
  140. if (y->left !=0)
  141. y->left->parent = p;
  142. y->parent = p->parent;
  143. if (p == *root)
  144. *root = y;
  145. else if (p == p->parent->left)
  146. p->parent->left = y;
  147. else
  148. p->parent->right = y;
  149. y->left = p;
  150. p->parent = y;
  151. }
  152. static void db_rotate_right(struct dbn *p,struct dbn **root)
  153. {
  154. struct dbn * y = p->left;
  155. p->left = y->right;
  156. if (y->right != 0)
  157. y->right->parent = p;
  158. y->parent = p->parent;
  159. if (p == *root)
  160. *root = y;
  161. else if (p == p->parent->right)
  162. p->parent->right = y;
  163. else
  164. p->parent->left = y;
  165. y->right = p;
  166. p->parent = y;
  167. }
  168. static void db_rebalance(struct dbn *p,struct dbn **root)
  169. {
  170. p->color = RED;
  171. while(p!=*root && p->parent->color==RED){ // rootは必ず黒で親は赤いので親の親は必ず存在する
  172. if (p->parent == p->parent->parent->left) {
  173. struct dbn *y = p->parent->parent->right;
  174. if (y && y->color == RED) {
  175. p->parent->color = BLACK;
  176. y->color = BLACK;
  177. p->parent->parent->color = RED;
  178. p = p->parent->parent;
  179. } else {
  180. if (p == p->parent->right) {
  181. p = p->parent;
  182. db_rotate_left(p, root);
  183. }
  184. p->parent->color = BLACK;
  185. p->parent->parent->color = RED;
  186. db_rotate_right(p->parent->parent, root);
  187. }
  188. } else {
  189. struct dbn* y = p->parent->parent->left;
  190. if (y && y->color == RED) {
  191. p->parent->color = BLACK;
  192. y->color = BLACK;
  193. p->parent->parent->color = RED;
  194. p = p->parent->parent;
  195. } else {
  196. if (p == p->parent->left) {
  197. p = p->parent;
  198. db_rotate_right(p, root);
  199. }
  200. p->parent->color = BLACK;
  201. p->parent->parent->color = RED;
  202. db_rotate_left(p->parent->parent, root);
  203. }
  204. }
  205. }
  206. (*root)->color=BLACK;
  207. }
  208. static void db_rebalance_erase(struct dbn *z,struct dbn **root)
  209. {
  210. struct dbn *y = z, *x = NULL, *x_parent = NULL;
  211. if (y->left == NULL)
  212. x = y->right;
  213. else if (y->right == NULL)
  214. x = y->left;
  215. else {
  216. y = y->right;
  217. while (y->left != NULL)
  218. y = y->left;
  219. x = y->right;
  220. }
  221. if (y != z) { // 左右が両方埋まっていた時 yをzの位置に持ってきてzを浮かせる
  222. z->left->parent = y;
  223. y->left = z->left;
  224. if (y != z->right) {
  225. x_parent = y->parent;
  226. if (x) x->parent = y->parent;
  227. y->parent->left = x;
  228. y->right = z->right;
  229. z->right->parent = y;
  230. } else
  231. x_parent = y;
  232. if (*root == z)
  233. *root = y;
  234. else if (z->parent->left == z)
  235. z->parent->left = y;
  236. else
  237. z->parent->right = y;
  238. y->parent = z->parent;
  239. { int tmp=y->color; y->color=z->color; z->color=tmp; }
  240. y = z;
  241. } else { // どちらか空いていた場合 xをzの位置に持ってきてzを浮かせる
  242. x_parent = y->parent;
  243. if (x) x->parent = y->parent;
  244. if (*root == z)
  245. *root = x;
  246. else if (z->parent->left == z)
  247. z->parent->left = x;
  248. else
  249. z->parent->right = x;
  250. }
  251. // ここまで色の移動の除いて通常の2分木と同じ
  252. if (y->color != RED) { // 赤が消える分には影響無し
  253. while (x != *root && (x == NULL || x->color == BLACK))
  254. if (x == x_parent->left) {
  255. struct dbn* w = x_parent->right;
  256. if (w->color == RED) {
  257. w->color = BLACK;
  258. x_parent->color = RED;
  259. db_rotate_left(x_parent, root);
  260. w = x_parent->right;
  261. }
  262. if ((w->left == NULL ||
  263. w->left->color == BLACK) &&
  264. (w->right == NULL ||
  265. w->right->color == BLACK)) {
  266. w->color = RED;
  267. x = x_parent;
  268. x_parent = x_parent->parent;
  269. } else {
  270. if (w->right == NULL ||
  271. w->right->color == BLACK) {
  272. if (w->left) w->left->color = BLACK;
  273. w->color = RED;
  274. db_rotate_right(w, root);
  275. w = x_parent->right;
  276. }
  277. w->color = x_parent->color;
  278. x_parent->color = BLACK;
  279. if (w->right) w->right->color = BLACK;
  280. db_rotate_left(x_parent, root);
  281. break;
  282. }
  283. } else { // same as above, with right <-> left.
  284. struct dbn* w = x_parent->left;
  285. if (w->color == RED) {
  286. w->color = BLACK;
  287. x_parent->color = RED;
  288. db_rotate_right(x_parent, root);
  289. w = x_parent->left;
  290. }
  291. if ((w->right == NULL ||
  292. w->right->color == BLACK) &&
  293. (w->left == NULL ||
  294. w->left->color == BLACK)) {
  295. w->color = RED;
  296. x = x_parent;
  297. x_parent = x_parent->parent;
  298. } else {
  299. if (w->left == NULL ||
  300. w->left->color == BLACK) {
  301. if (w->right) w->right->color = BLACK;
  302. w->color = RED;
  303. db_rotate_left(w, root);
  304. w = x_parent->left;
  305. }
  306. w->color = x_parent->color;
  307. x_parent->color = BLACK;
  308. if (w->left) w->left->color = BLACK;
  309. db_rotate_right(x_parent, root);
  310. break;
  311. }
  312. }
  313. if (x) x->color = BLACK;
  314. }
  315. }
  316. struct dbn* db_insert(struct dbt *table,void* key,void* data)
  317. {
  318. struct dbn *p,*priv;
  319. int c,hash;
  320. hash = table->hash(table,key) % HASH_SIZE;
  321. for(c=0,priv=NULL ,p = table->ht[hash];p;){
  322. c=table->cmp(table,key,p->key);
  323. if(c==0){ // replace
  324. if (table->release)
  325. table->release(p, 3);
  326. p->data=data;
  327. p->key=key;
  328. return p;
  329. }
  330. priv=p;
  331. if(c<0){
  332. p=p->left;
  333. } else {
  334. p=p->right;
  335. }
  336. }
  337. #ifdef MALLOC_DBN
  338. p=malloc_dbn();
  339. #else
  340. CREATE(p, struct dbn, 1);
  341. #endif
  342. if(p==NULL){
  343. printf("out of memory : db_insert\n");
  344. return NULL;
  345. }
  346. p->parent= NULL;
  347. p->left = NULL;
  348. p->right = NULL;
  349. p->key = key;
  350. p->data = data;
  351. p->color = RED;
  352. if(c==0){ // hash entry is empty
  353. table->ht[hash] = p;
  354. p->color = BLACK;
  355. } else {
  356. if(c<0){ // left node
  357. priv->left = p;
  358. p->parent=priv;
  359. } else { // right node
  360. priv->right = p;
  361. p->parent=priv;
  362. }
  363. if(priv->color==RED){ // must rebalance
  364. db_rebalance(p,&table->ht[hash]);
  365. }
  366. }
  367. return p;
  368. }
  369. void* db_erase(struct dbt *table,void* key)
  370. {
  371. void *data;
  372. struct dbn *p;
  373. int c,hash;
  374. hash = table->hash(table,key) % HASH_SIZE;
  375. for(c=0,p = table->ht[hash];p;){
  376. c=table->cmp(table,key,p->key);
  377. if(c==0)
  378. break;
  379. if(c<0)
  380. p=p->left;
  381. else
  382. p=p->right;
  383. }
  384. if(!p)
  385. return NULL;
  386. data=p->data;
  387. db_rebalance_erase(p,&table->ht[hash]);
  388. #ifdef MALLOC_DBN
  389. free_dbn(p);
  390. #else
  391. free(p);
  392. #endif
  393. return data;
  394. }
  395. void db_foreach(struct dbt *table,int (*func)(void*,void*,va_list),...)
  396. {
  397. int i,sp;
  398. // red-black treeなので64個stackがあれば2^32個ノードまで大丈夫
  399. struct dbn *p,*pn,*stack[64];
  400. va_list ap;
  401. va_start(ap,func);
  402. for(i=0;i<HASH_SIZE;i++){
  403. if((p=table->ht[i])==NULL)
  404. continue;
  405. sp=0;
  406. while(1){
  407. if (!p->data) {
  408. printf("Warning: no data for key %d in db_foreach (db.c) !\n",(int)p->key);
  409. } else {
  410. func(p->key, p->data, ap);
  411. }
  412. if((pn=p->left)!=NULL){
  413. if(p->right){
  414. stack[sp++]=p->right;
  415. }
  416. p=pn;
  417. } else {
  418. if(p->right){
  419. p=p->right;
  420. } else {
  421. if(sp==0)
  422. break;
  423. p=stack[--sp];
  424. }
  425. }
  426. }
  427. }
  428. va_end(ap);
  429. }
  430. void db_final(struct dbt *table,int (*func)(void*,void*,va_list),...)
  431. {
  432. int i,sp;
  433. struct dbn *p,*pn,*stack[64];
  434. va_list ap;
  435. va_start(ap,func);
  436. for(i=0;i<HASH_SIZE;i++){
  437. if((p=table->ht[i])==NULL)
  438. continue;
  439. sp=0;
  440. while(1){
  441. if(func)
  442. func(p->key,p->data,ap);
  443. if((pn=p->left)!=NULL){
  444. if(p->right){
  445. stack[sp++]=p->right;
  446. }
  447. } else {
  448. if(p->right){
  449. pn=p->right;
  450. } else {
  451. if(sp==0)
  452. break;
  453. pn=stack[--sp];
  454. }
  455. }
  456. #ifdef MALLOC_DBN
  457. free_dbn(p);
  458. #else
  459. free(p);
  460. #endif
  461. p=pn;
  462. }
  463. }
  464. free(table);
  465. va_end(ap);
  466. }