00001
00002
00003
00004
00005
00006
00007 static int map_sizes[] = {
00008 sizeof(struct map_node_int64),
00009 sizeof(struct map_node_stat),
00010 sizeof(struct map_node_str),
00011 0
00012 };
00013
00014 static unsigned string_hash(const char *key1, const char *key2)
00015 {
00016 int hash = 0, count = 0;
00017 char *v1 = (char *)key1;
00018 char *v2 = (char *)key2;
00019 while (*v1 && count++ < 5) {
00020 hash += *v1++;
00021 }
00022 while (v2 && *v2 && count++ < 5) {
00023 hash += *v2++;
00024 }
00025 return hash_long((unsigned long)hash, HASH_TABLE_BITS);
00026 }
00027
00028 static unsigned mixed_hash(const char *key1, long key2)
00029 {
00030 int hash = 0, count = 0;
00031 char *v = (char *)key1;
00032 while (v && *v && count++ < 5)
00033 hash += *v++;
00034 return hash_long((unsigned long)(hash ^ key2), HASH_TABLE_BITS);
00035 }
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 MAP _stp_map_new(unsigned max_entries, enum valtype type)
00048 {
00049 size_t size;
00050 MAP m = (MAP) _stp_valloc(sizeof(struct map_root));
00051 if (m == NULL)
00052 return NULL;
00053
00054 INIT_LIST_HEAD(&m->head);
00055
00056 m->maxnum = max_entries;
00057 m->type = type;
00058 if (type >= END) {
00059 dbug ("map_new: unknown type %d\n", type);
00060 return NULL;
00061 }
00062
00063 if (max_entries) {
00064 void *tmp;
00065 int i;
00066 struct list_head *e;
00067
00068 INIT_LIST_HEAD(&m->pool);
00069 size = map_sizes[type];
00070 tmp = _stp_valloc(max_entries * size);
00071
00072 for (i = max_entries - 1; i >= 0; i--) {
00073 e = i * size + tmp;
00074 dbug ("e=%lx\n", (long)e);
00075 list_add(e, &m->pool);
00076 }
00077 m->membuf = tmp;
00078 }
00079 return m;
00080 }
00081
00082 static void map_free_strings(MAP map, struct map_node *n)
00083 {
00084 struct map_node_str *m = (struct map_node_str *)n;
00085 dbug ("n = %lx\n", (long)n);
00086 if (map->type == STRING) {
00087 dbug ("val STRING %lx\n", (long)m->str);
00088 if (m->str)
00089 _stp_free(m->str);
00090 }
00091 if (m->n.key1type == STR) {
00092 dbug ("key1 STR %lx\n", (long)key1str(m));
00093 if (key1str(m))
00094 _stp_free(key1str(m));
00095 }
00096 if (m->n.key2type == STR) {
00097 dbug ("key2 STR %lx\n", (long)key2str(m));
00098 if (key2str(m))
00099 _stp_free(key2str(m));
00100 }
00101 }
00102
00103
00104
00105
00106
00107
00108 void _stp_map_key_del(MAP map)
00109 {
00110 struct map_node *m;
00111
00112 dbug ("create=%d key=%lx\n", map->create, (long)map->key);
00113 if (map == NULL)
00114 return;
00115
00116 if (map->create) {
00117 map->create = 0;
00118 map->key = NULL;
00119 return;
00120 }
00121
00122 if (map->key == NULL)
00123 return;
00124
00125 m = (struct map_node *)map->key;
00126
00127
00128 hlist_del_init(&m->hnode);
00129
00130
00131 list_del(&m->lnode);
00132
00133
00134 map_free_strings(map, (struct map_node *)map->key);
00135
00136 if (map->maxnum)
00137 list_add(&m->lnode, &map->pool);
00138 else
00139 _stp_free(m);
00140
00141 map->key = NULL;
00142 map->num--;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 struct map_node *_stp_map_start(MAP map)
00154 {
00155 if (map == NULL)
00156 return NULL;
00157
00158 dbug ("%lx\n", (long)map->head.next);
00159
00160 if (list_empty(&map->head))
00161 return NULL;
00162
00163 return (struct map_node *)map->head.next;
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 struct map_node *_stp_map_iter(MAP map, struct map_node *m)
00177 {
00178 if (map == NULL)
00179 return NULL;
00180
00181 dbug ("%lx next=%lx prev=%lx map->head.next=%lx\n", (long)m,
00182 (long)m->lnode.next, (long)m->lnode.prev, (long)map->head.next);
00183
00184 if (m->lnode.next == &map->head)
00185 return NULL;
00186
00187 return (struct map_node *)m->lnode.next;
00188 }
00189
00190
00191
00192
00193
00194
00195 void _stp_map_del(MAP map)
00196 {
00197 if (map == NULL)
00198 return;
00199
00200 if (!list_empty(&map->head)) {
00201 struct map_node *ptr = (struct map_node *)map->head.next;
00202 while (ptr && ptr != (struct map_node *)&map->head) {
00203 map_free_strings(map, ptr);
00204 ptr = (struct map_node *)ptr->lnode.next;
00205 }
00206 }
00207 _stp_vfree(map->membuf);
00208 _stp_vfree(map);
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 void _stp_map_key_long_long(MAP map, long key1, long key2)
00224 {
00225 unsigned hv;
00226 struct hlist_head *head;
00227 struct hlist_node *e;
00228
00229 if (map == NULL)
00230 return;
00231
00232 hv = hash_long(key1 ^ key2, HASH_TABLE_BITS);
00233 head = &map->hashes[hv];
00234
00235 dbug ("hash for %ld,%ld is %d\n", key1, key2, hv);
00236
00237 hlist_for_each(e, head) {
00238 struct map_node *n =
00239 (struct map_node *)((long)e - sizeof(struct hlist_node));
00240 dbug ("n =%lx key=%ld,%ld\n", (long)n, n->key1.val, n->key2.val);
00241 if (key1 == n->key1.val && key2 == n->key2.val) {
00242 map->key = n;
00243 dbug ("saving key %lx\n", (long)map->key);
00244 map->create = 0;
00245 return;
00246 }
00247 }
00248
00249 map->c_key1.val = key1;
00250 map->c_key2.val = key2;
00251 map->c_key1type = LONG;
00252 map->c_key2type = LONG;
00253 map->c_keyhead = head;
00254 map->create = 1;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 void _stp_map_key_str_str(MAP map, char *key1, char *key2)
00267 {
00268 unsigned hv;
00269 struct hlist_head *head;
00270 struct hlist_node *e;
00271
00272 if (map == NULL)
00273 return;
00274
00275 if (key1 == NULL) {
00276 map->key = NULL;
00277 return;
00278 }
00279
00280 hv = string_hash(key1, key2);
00281 head = &map->hashes[hv];
00282
00283 dbug ("hash for %s,%s is %d\n", key1, key2, hv);
00284
00285 hlist_for_each(e, head) {
00286 struct map_node *n =
00287 (struct map_node *)((long)e - sizeof(struct hlist_node));
00288 dbug ("e =%lx key=%s,%s\n", (long)e, n->key1.str,n->key2.str);
00289 if (strcmp(key1, n->key1.str) == 0
00290 && (key2 == NULL || strcmp(key2, n->key2.str) == 0)) {
00291 map->key = n;
00292 dbug ("saving key %lx\n", (long)map->key);
00293 map->create = 0;
00294 return;
00295 }
00296 }
00297
00298 map->c_key1.str = key1;
00299 map->c_key2.str = key2;
00300 map->c_key1type = STR;
00301 map->c_key2type = STR;
00302 map->c_keyhead = head;
00303 map->create = 1;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 void _stp_map_key_str_long(MAP map, char *key1, long key2)
00316 {
00317 unsigned hv;
00318 struct hlist_head *head;
00319 struct hlist_node *e;
00320
00321 if (map == NULL)
00322 return;
00323
00324 if (key1 == NULL) {
00325 map->key = NULL;
00326 return;
00327 }
00328
00329 hv = mixed_hash(key1, key2);
00330 head = &map->hashes[hv];
00331
00332 dbug ("hash for %s,%ld is %d\n", key1, key2, hv);
00333
00334 hlist_for_each(e, head) {
00335 struct map_node *n =
00336 (struct map_node *)((long)e - sizeof(struct hlist_node));
00337 dbug ("e =%lx key=%s,%ld\n", (long)e, n->key1.str,(long)n->key2.val);
00338 if (strcmp(key1, n->key1.str) == 0 && key2 == n->key2.val) {
00339 map->key = n;
00340 dbug ("saving key %lx\n", (long)map->key);
00341 map->create = 0;
00342 return;
00343 }
00344 }
00345
00346 map->c_key1.str = key1;
00347 map->c_key2.val = key2;
00348 map->c_key1type = STR;
00349 map->c_key2type = LONG;
00350 map->c_keyhead = head;
00351 map->create = 1;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 void _stp_map_key_long_str(MAP map, long key1, char *key2)
00364 {
00365 unsigned hv;
00366 struct hlist_head *head;
00367 struct hlist_node *e;
00368
00369 if (map == NULL)
00370 return;
00371
00372 hv = mixed_hash(key2, key1);
00373 head = &map->hashes[hv];
00374 dbug ("hash for %ld,%s is %d\n", key1, key2, hv);
00375
00376 hlist_for_each(e, head) {
00377 struct map_node *n =
00378 (struct map_node *)((long)e - sizeof(struct hlist_node));
00379 dbug ("e =%lx key=%ld,%s\n", (long)e, n->key1.val,n->key2.str);
00380 if (key1 == n->key1.val && strcmp(key2, n->key2.str) == 0) {
00381 map->key = n;
00382 dbug ("saving key %lx\n", (long)map->key);
00383 map->create = 0;
00384 return;
00385 }
00386 }
00387
00388 map->c_key1.val = key1;
00389 map->c_key2.str = key2;
00390 map->c_key1type = LONG;
00391 map->c_key2type = STR;
00392 map->c_keyhead = head;
00393 map->create = 1;
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 void _stp_map_key_str(MAP map, char *key)
00405 {
00406 if (map == NULL)
00407 return;
00408 _stp_map_key_str_str(map, key, NULL);
00409 map->c_key2type = NONE;
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 void _stp_map_key_long(MAP map, long key)
00421 {
00422 if (map == NULL)
00423 return;
00424 _stp_map_key_long_long(map, key, 0);
00425 map->c_key2type = NONE;
00426 }
00427
00428
00429
00430 static void map_copy_keys(MAP map, struct map_node *m)
00431 {
00432 m->key1type = map->c_key1type;
00433 m->key2type = map->c_key2type;
00434 switch (map->c_key1type) {
00435 case STR:
00436 m->key1.str = _stp_alloc(strlen(map->c_key1.str) + 1);
00437 strcpy(m->key1.str, map->c_key1.str);
00438 break;
00439 case LONG:
00440 m->key1.val = map->c_key1.val;
00441 break;
00442 case NONE:
00443
00444 break;
00445 }
00446 switch (map->c_key2type) {
00447 case STR:
00448 m->key2.str = _stp_alloc(strlen(map->c_key2.str) + 1);
00449 strcpy(m->key2.str, map->c_key2.str);
00450 break;
00451 case LONG:
00452 m->key2.val = map->c_key2.val;
00453 break;
00454 case NONE:
00455 break;
00456 }
00457
00458
00459 hlist_add_head(&m->hnode, map->c_keyhead);
00460
00461 map->key = m;
00462 map->create = 0;
00463 map->num++;
00464 }
00465
00466 static void __stp_map_set_int64(MAP map, int64_t val, int add)
00467 {
00468 struct map_node_int64 *m;
00469
00470 if (map == NULL)
00471 return;
00472
00473 if (map->create) {
00474 if (val == 0)
00475 return;
00476
00477 if (map->maxnum) {
00478 if (list_empty(&map->pool)) {
00479 if (map->no_wrap) {
00480
00481 return;
00482 }
00483 m = (struct map_node_int64 *)map->head.next;
00484 hlist_del_init(&m->n.hnode);
00485 map_free_strings(map, (struct map_node *)m);
00486 dbug ("got %lx off head\n", (long)m);
00487 } else {
00488 m = (struct map_node_int64 *)map->pool.next;
00489 dbug ("got %lx off pool\n", (long)m);
00490 }
00491 list_move_tail(&m->n.lnode, &map->head);
00492 } else {
00493 m = (struct map_node_int64 *)
00494 _stp_calloc(sizeof(struct map_node_int64));
00495
00496 list_add_tail(&m->n.lnode, &map->head);
00497 }
00498
00499
00500 map_copy_keys(map, &m->n);
00501
00502
00503 m->val = val;
00504 } else {
00505 if (map->key == NULL)
00506 return;
00507
00508 if (val) {
00509 m = (struct map_node_int64 *)map->key;
00510 if (add)
00511 m->val += val;
00512 else
00513 m->val = val;
00514 } else if (!add) {
00515
00516 _stp_map_key_del(map);
00517 }
00518 }
00519 }
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 void _stp_map_set_int64(MAP map, int64_t val)
00532 {
00533 __stp_map_set_int64 (map, val, 0);
00534 }
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 void _stp_map_add_int64(MAP map, int64_t val)
00549 {
00550 __stp_map_set_int64 (map, val, 1);
00551 }
00552
00553
00554
00555
00556
00557
00558 int64_t _stp_map_get_int64(MAP map)
00559 {
00560 struct map_node_int64 *m;
00561 if (map == NULL || map->create || map->key == NULL)
00562 return 0;
00563 dbug ("%lx\n", (long)map->key);
00564 m = (struct map_node_int64 *)map->key;
00565 return m->val;
00566 }
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 void _stp_map_set_str(MAP map, char *val)
00579 {
00580 struct map_node_str *m;
00581
00582 if (map == NULL)
00583 return;
00584
00585 if (map->create) {
00586 if (val == NULL)
00587 return;
00588
00589 if (map->maxnum) {
00590 if (list_empty(&map->pool)) {
00591 if (map->no_wrap) {
00592
00593 return;
00594 }
00595 m = (struct map_node_str *)map->head.next;
00596 hlist_del_init(&m->n.hnode);
00597 map_free_strings(map, (struct map_node *)m);
00598 dbug ("got %lx off head\n", (long)m);
00599 } else {
00600 m = (struct map_node_str *)map->pool.next;
00601 dbug ("got %lx off pool\n", (long)m);
00602 }
00603 list_move_tail(&m->n.lnode, &map->head);
00604 } else {
00605 m = (struct map_node_str *)
00606 _stp_calloc(sizeof(struct map_node_str));
00607
00608 list_add_tail(&m->n.lnode, &map->head);
00609 }
00610
00611
00612 map_copy_keys(map, &m->n);
00613
00614
00615 m->str = _stp_alloc(strlen(val) + 1);
00616 strcpy(m->str, val);
00617 } else {
00618 if (map->key == NULL)
00619 return;
00620
00621 if (val) {
00622 m = (struct map_node_str *)map->key;
00623 if (m->str)
00624 _stp_free(m->str);
00625 m->str = _stp_alloc(strlen(val) + 1);
00626 strcpy(m->str, val);
00627 } else {
00628
00629 _stp_map_key_del(map);
00630 }
00631 }
00632 }
00633
00634
00635
00636
00637
00638
00639 char *_stp_map_get_str(MAP map)
00640 {
00641 struct map_node_str *m;
00642 if (map == NULL || map->create || map->key == NULL)
00643 return NULL;
00644 dbug ("%lx\n", (long)map->key);
00645 m = (struct map_node_str *)map->key;
00646 return m->str;
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 void _stp_map_set_stat(MAP map, stat * stats)
00664 {
00665 struct map_node_stat *m;
00666
00667 if (map == NULL)
00668 return;
00669 dbug ("set_stat %lx\n", (long)map->key);
00670
00671 if (map->create) {
00672 if (stats == NULL)
00673 return;
00674
00675 if (map->maxnum) {
00676 if (list_empty(&map->pool)) {
00677 if (map->no_wrap) {
00678
00679 return;
00680 }
00681 m = (struct map_node_stat *)map->head.next;
00682 hlist_del_init(&m->n.hnode);
00683 map_free_strings(map, (struct map_node *)m);
00684 dbug ("got %lx off head\n", (long)m);
00685 } else {
00686 m = (struct map_node_stat *)map->pool.next;
00687 dbug ("got %lx off pool\n", (long)m);
00688 }
00689 list_move_tail(&m->n.lnode, &map->head);
00690 } else {
00691 m = (struct map_node_stat *)
00692 _stp_calloc(sizeof(struct map_node_stat));
00693
00694 list_add_tail(&m->n.lnode, &map->head);
00695 }
00696
00697
00698 map_copy_keys(map, &m->n);
00699
00700
00701 memcpy(&m->stats, stats, sizeof(stat));
00702 } else {
00703 if (map->key == NULL)
00704 return;
00705
00706 if (stats) {
00707 m = (struct map_node_stat *)map->key;
00708 memcpy(&m->stats, stats, sizeof(stat));
00709 } else {
00710
00711 _stp_map_key_del(map);
00712 }
00713 }
00714 }
00715
00716
00717
00718
00719
00720
00721
00722 stat *_stp_map_get_stat(MAP map)
00723 {
00724 struct map_node_stat *m;
00725 if (map == NULL || map->create || map->key == NULL)
00726 return NULL;
00727 dbug ("%lx\n", (long)map->key);
00728 m = (struct map_node_stat *)map->key;
00729 return &m->stats;
00730 }
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743 void _stp_map_stat_add(MAP map, int64_t val)
00744 {
00745 struct map_node_stat *m;
00746 if (map == NULL)
00747 return;
00748
00749 if (map->create) {
00750 stat st = { 1, val, val, val };
00751
00752 _stp_map_set_stat(map, &st);
00753 return;
00754 }
00755
00756 if (map->key == NULL)
00757 return;
00758
00759 dbug ("add_stat %lx\n", (long)map->key);
00760 m = (struct map_node_stat *)map->key;
00761 m->stats.count++;
00762 m->stats.sum += val;
00763 if (val > m->stats.max)
00764 m->stats.max = val;
00765 if (val < m->stats.min)
00766 m->stats.min = val;
00767
00768 }
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 MAP _stp_list_new(unsigned max_entries, enum valtype type)
00784 {
00785 MAP map = _stp_map_new (max_entries, type);
00786 map->no_wrap = 1;
00787 return map;
00788 }
00789
00790
00791
00792
00793
00794
00795 void _stp_list_clear(MAP map)
00796 {
00797 if (map == NULL)
00798 return;
00799
00800 if (!list_empty(&map->head)) {
00801 struct map_node *ptr = (struct map_node *)map->head.next;
00802
00803 while (ptr && ptr != (struct map_node *)&map->head) {
00804 struct map_node *next = (struct map_node *)ptr->lnode.next;
00805
00806
00807 hlist_del_init(&ptr->hnode);
00808
00809
00810 list_del(&ptr->lnode);
00811
00812
00813 map_free_strings(map, ptr);
00814
00815 if (map->maxnum)
00816 list_add(&ptr->lnode, &map->pool);
00817 else
00818 _stp_free(ptr);
00819
00820 map->num--;
00821 ptr = next;
00822 }
00823 }
00824
00825 if (map->num != 0) {
00826 dlog ("ERROR: list is supposed to be empty (has %d)\n", map->num);
00827 }
00828 }
00829
00830
00831
00832
00833
00834
00835 inline void _stp_list_add_str(MAP map, char *str)
00836 {
00837 _stp_map_key_long(map, map->num);
00838 _stp_map_set_str(map, str);
00839 }
00840
00841
00842
00843
00844
00845
00846 inline void _stp_list_add_int64(MAP map, int64_t val)
00847 {
00848 _stp_map_key_long(map, map->num);
00849 _stp_map_set_int64(map, val);
00850 }
00851
00852
00853
00854
00855
00856
00857 inline int _stp_list_size(MAP map)
00858 {
00859 return map->num;
00860 }