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