diff options
author | hunt <hunt> | 2005-05-17 08:02:30 +0000 |
---|---|---|
committer | hunt <hunt> | 2005-05-17 08:02:30 +0000 |
commit | 43614f5d7e0d18f553c0ee2a4e195d7b8f63be1f (patch) | |
tree | 89edd85aa491b4f9632d10705fcd68c04fc98db3 /runtime/map-keys.c | |
parent | 30add090cbcbb6367c06c8bcc3c270e60c2f928e (diff) | |
download | systemtap-steved-43614f5d7e0d18f553c0ee2a4e195d7b8f63be1f.tar.gz systemtap-steved-43614f5d7e0d18f553c0ee2a4e195d7b8f63be1f.tar.xz systemtap-steved-43614f5d7e0d18f553c0ee2a4e195d7b8f63be1f.zip |
Rewritten maps and other updated files.
Diffstat (limited to 'runtime/map-keys.c')
-rw-r--r-- | runtime/map-keys.c | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/runtime/map-keys.c b/runtime/map-keys.c new file mode 100644 index 00000000..37308179 --- /dev/null +++ b/runtime/map-keys.c @@ -0,0 +1,416 @@ +/* -*- linux-c -*- */ + +#include "map.h" + +#define JOIN(x,y) JOINx(x,y) +#define JOINx(x,y) x##_##y + +#if defined (KEY1_TYPE) +#define KEY_ARITY 1 +#if KEY1_TYPE == STRING +#define KEY1TYPE char* +#define KEY1NAME str +#define KEY1STOR char key1[MAP_STRING_LENGTH] +#define NEED_STRING_KEYS +#else +#define KEY1TYPE int64_t +#define KEY1NAME int64 +#define KEY1STOR int64_t key1 +#define NEED_INT64_KEYS +#endif +#define KEY1_EQ_P JOIN(KEY1NAME,eq_p) +#define KEY1_HASH JOIN(KEY1NAME,hash) +#endif /* defined(KEY1_TYPE) */ + +#if defined (KEY2_TYPE) +#undef KEY_ARITY +#define KEY_ARITY 2 +#if KEY2_TYPE == STRING +#define KEY2TYPE char* +#define KEY2NAME str +#define KEY2STOR char key2[MAP_STRING_LENGTH] +#define NEED_STRING_KEYS +#else +#define KEY2TYPE int64_t +#define KEY2NAME int64 +#define KEY2STOR int64_t key2 +#define NEED_INT64_KEYS +#endif +#define KEY2_EQ_P JOIN(KEY2NAME,eq_p) +#define KEY2_HASH JOIN(KEY2NAME,hash) +#endif /* defined(KEY2_TYPE) */ + +#if defined (KEY3_TYPE) +#undef KEY_ARITY +#define KEY_ARITY 3 +#if KEY3_TYPE == STRING +#define KEY3TYPE char* +#define KEY3NAME str +#define KEY3STOR char key3[MAP_STRING_LENGTH] +#define NEED_STRING_KEYS +#else +#define KEY3TYPE int64_t +#define KEY3NAME int64 +#define KEY3STOR int64_t key3 +#define NEED_INT64_KEYS +#endif +#define KEY3_EQ_P JOIN(KEY3NAME,eq_p) +#define KEY3_HASH JOIN(KEY3NAME,hash) +#endif /* defined(KEY3_TYPE) */ + +#if defined (KEY4_TYPE) +#undef KEY_ARITY +#define KEY_ARITY 4 +#if KEY4_TYPE == STRING +#define KEY4TYPE char* +#define KEY4NAME str +#define KEY4STOR char key4[MAP_STRING_LENGTH] +#define NEED_STRING_KEYS +#else +#define KEY4TYPE int64_t +#define KEY4NAME int64 +#define KEY4STOR int64_t key4 +#define NEED_INT64_KEYS +#endif +#define KEY4_EQ_P JOIN(KEY4NAME,eq_p) +#define KEY4_HASH JOIN(KEY4NAME,hash) +#endif /* defined(KEY4_TYPE) */ + +#if defined (KEY5_TYPE) +#undef KEY_ARITY +#define KEY_ARITY 5 +#if KEY5_TYPE == STRING +#define KEY5TYPE char* +#define KEY5NAME str +#define KEY5STOR char key5[MAP_STRING_LENGTH] +#define NEED_STRING_KEYS +#else +#define KEY5TYPE int64_t +#define KEY5NAME int64 +#define KEY5STOR int64_t key5 +#define NEED_INT64_KEYS +#endif +#define KEY5_EQ_P JOIN(KEY5NAME,eq_p) +#define KEY5_HASH JOIN(KEY5NAME,hash) +#endif /* defined(KEY5_TYPE) */ + +#if KEY_ARITY == 1 +#define KEYSYM(x) JOIN(x,KEY1NAME) +#define ALLKEYS(x) x##1 +#define ALLKEYSD(x) KEY1TYPE x##1 +#elif KEY_ARITY == 2 +#define JOIN2(x,y,z) JOIN2x(x,y,z) +#define JOIN2x(x,y,z) x##_##y##_##z +#define KEYSYM(x) JOIN2(x,KEY1NAME,KEY2NAME) +#define ALLKEYS(x) x##1, x##2 +#define ALLKEYSD(x) KEY1TYPE x##1, KEY2TYPE x##2 +#elif KEY_ARITY == 3 +#define JOIN3(a,b,c,d) JOIN3x(a,b,c,d) +#define JOIN3x(a,b,c,d) a##_##b##_##c##_##d +#define KEYSYM(x) JOIN3(x,KEY1NAME,KEY2NAME,KEY3NAME) +#define ALLKEYS(x) x##1, x##2, x##3 +#define ALLKEYSD(x) KEY1TYPE x##1, KEY2TYPE x##2, KEY3TYPE x##3 +#elif KEY_ARITY == 4 +#define JOIN4(a,b,c,d,e) JOIN4x(a,b,c,d,e) +#define JOIN4x(a,b,c,d,e) a##_##b##_##c##_##d##_##e +#define KEYSYM(x) JOIN4(x,KEY1NAME,KEY2NAME,KEY3NAME,KEY4NAME) +#define ALLKEYS(x) x##1, x##2, x##3, x##4 +#define ALLKEYSD(x) KEY1TYPE x##1, KEY2TYPE x##2, KEY3TYPE x##3, KEY4TYPE x##4 +#elif KEY_ARITY == 5 +#define JOIN5(a,b,c,d,e,f) JOIN5x(a,b,c,d,e,f) +#define JOIN5x(a,b,c,d,e,f) a##_##b##_##c##_##d##_##e##_##f +#define KEYSYM(x) JOIN5(x,KEY1NAME,KEY2NAME,KEY3NAME,KEY4NAME,KEY5NAME) +#define ALLKEYS(x) x##1, x##2, x##3, x##4, x##5 +#define ALLKEYSD(x) KEY1TYPE x##1, KEY2TYPE x##2, KEY3TYPE x##3, KEY4TYPE x##4, KEY5TYPE x##5 +#endif + +/* */ +struct KEYSYM(map_node) { + /* list of other nodes in the map */ + struct list_head lnode; + /* list of nodes with the same hash value */ + struct hlist_node hnode; + /* pointer back to the map struct */ + struct map_root *map; + + KEY1STOR; +#if KEY_ARITY > 1 + KEY2STOR; +#if KEY_ARITY > 2 + KEY3STOR; +#if KEY_ARITY > 3 + KEY4STOR; +#if KEY_ARITY > 4 + KEY5STOR; +#endif +#endif +#endif +#endif +}; + +#define type_to_enum(type) \ + ({ \ + int ret; \ + if (__builtin_types_compatible_p (type, char*)) \ + ret = STRING; \ + else \ + ret = INT64; \ + ret; \ + }) + +static key_data KEYSYM(map_get_key) (struct map_node *mn, int n, int *type) +{ + key_data ptr; + struct KEYSYM(map_node) *m = (struct KEYSYM(map_node) *)mn; + + dbug ("m=%lx\n", (long)m); + if (n > KEY_ARITY || n < 1) { + if (type) + *type = END; + return (key_data)(int64_t)0; + } + + switch (n) { + case 1: + ptr = (key_data)m->key1; + if (type) + *type = type_to_enum(KEY1TYPE); + break; +#if KEY_ARITY > 1 + case 2: + ptr = (key_data)m->key2; + if (type) + *type = type_to_enum(KEY2TYPE); + + break; +#if KEY_ARITY > 2 + case 3: + ptr = (key_data)m->key3; + if (type) + *type = type_to_enum(KEY3TYPE); + break; +#if KEY_ARITY > 3 + case 4: + ptr = (key_data)m->key4; + if (type) + *type = type_to_enum(KEY4TYPE); + break; +#if KEY_ARITY > 4 + case 5: + ptr = (key_data)m->key5; + if (type) + *type = type_to_enum(KEY5TYPE); + break; +#endif +#endif +#endif +#endif + default: + ptr = (key_data)(int64_t)0; + if (type) + *type = END; + } + return ptr; +} + + +static void KEYSYM(map_copy_keys) (MAP map, struct map_node *n) +{ + struct KEYSYM(map_node) *m = (struct KEYSYM(map_node) *)n; +#if KEY1_TYPE == STRING + str_copy (m->key1, map->c_key[0].strp); +#else + m->key1 = map->c_key[0].val; +#endif +#if KEY_ARITY > 1 +#if KEY2_TYPE == STRING + str_copy (m->key2, map->c_key[1].strp); +#else + m->key2 = map->c_key[1].val; +#endif +#if KEY_ARITY > 2 +#if KEY3_TYPE == STRING + str_copy (m->key3, map->c_key[2].strp); +#else + m->key3 = map->c_key[2].val; +#endif +#if KEY_ARITY > 3 +#if KEY4_TYPE == STRING + str_copy (m->key4, map->c_key[3].strp); +#else + m->key4 = map->c_key[3].val; +#endif +#if KEY_ARITY > 4 +#if KEY5_TYPE == STRING + str_copy (m->key5, map->c_key[4].strp); +#else + m->key5 = map->c_key[4].val; +#endif +#endif +#endif +#endif +#endif +} + + +static unsigned int KEYSYM(hash) (ALLKEYSD(key)) +{ + unsigned int hash = KEY1_HASH(key1); +#if KEY_ARITY > 1 + hash ^= KEY2_HASH(key2); +#if KEY_ARITY > 2 + hash ^= KEY3_HASH(key3); +#if KEY_ARITY > 3 + hash ^= KEY4_HASH(key4); +#if KEY_ARITY > 4 + hash ^= KEY5_HASH(key5); +#endif +#endif +#endif +#endif + return (unsigned int) hash; +} + +/* _stp_map_new_key1_key2 (num, STAT, LINEAR, start, end, interval) */ +/* _stp_map_new_key1_key2 (num, STAT, LOG, buckets) */ + +MAP KEYSYM(_stp_map_new) (unsigned max_entries, int valtype, ...) +{ + int htype, buckets=0, start=0, stop=0, interval=0; + MAP m; + + htype = valtype >> 8; + dbug ("htype=%d\n", htype); + + if (htype != HIST_NONE) { + va_list ap; + va_start (ap, valtype); + + if (htype == HIST_LOG) { + buckets = va_arg(ap, int); + dbug ("buckets=%d\n", buckets); + } else { + start = va_arg(ap, int); + stop = va_arg(ap, int); + interval = va_arg(ap, int); + dbug ("start=%d stop=%d interval=%d\n", start, stop, interval); + } + va_end (ap); + } + switch (htype) { + case HIST_NONE: + m = _stp_map_new (max_entries, valtype & 0x0f, + sizeof(struct KEYSYM(map_node)), 0); + break; + case HIST_LOG: + m = _stp_map_new_hstat_log (max_entries, sizeof(struct KEYSYM(map_node)), + buckets); + break; + case HIST_LINEAR: + m = _stp_map_new_hstat_linear (max_entries, sizeof(struct KEYSYM(map_node)), + start, stop, interval); + break; + default: + dbug ("ERROR: unknown histogram type %d\n", htype); + m = NULL; + } + + if (m) { + m->copy_keys = KEYSYM(map_copy_keys); + m->get_key = KEYSYM(map_get_key); + } + return m; +} + + +#define SETKEYS2(key, n) { \ + if (__builtin_types_compatible_p (typeof (key), char[])) { \ + map->c_key[n].strp = (char *)key; \ + } else { \ + map->c_key[n].val = (int64_t)key; \ + } \ + } + +void KEYSYM(_stp_map_key) (MAP map, ALLKEYSD(key)) +{ + unsigned int hv; + struct hlist_head *head; + struct hlist_node *e; + + if (map == NULL) + return; + + hv = KEYSYM(hash) (ALLKEYS(key)); + head = &map->hashes[hv]; + + hlist_for_each(e, head) { + struct KEYSYM(map_node) *n = + (struct KEYSYM(map_node) *)((long)e - sizeof(struct hlist_node)); + //dbug ("n =%lx key=" EACHKEY(%ld) "\n", (long)n, n->key1.val, n->key2.val); + if (KEY1_EQ_P(n->key1, key1) +#if KEY_ARITY > 1 + && KEY2_EQ_P(n->key2, key2) +#if KEY_ARITY > 2 + && KEY3_EQ_P(n->key3, key3) +#if KEY_ARITY > 3 + && KEY4_EQ_P(n->key4, key4) +#if KEY_ARITY > 4 + && KEY5_EQ_P(n->key5, key5) +#endif +#endif +#endif +#endif + ) { + map->key = (struct map_node *)n; + dbug ("saving key %lx\n", (long)map->key); + map->create = 0; + return; + } + } + + dbug ("key not found\n"); + SETKEYS2 (key1, 0); +#if KEY_ARITY > 1 + SETKEYS2 (key2, 1); +#if KEY_ARITY > 2 + SETKEYS2 (key3, 2); +#if KEY_ARITY > 3 + SETKEYS2 (key4, 3); +#if KEY_ARITY > 4 + SETKEYS2 (key5, 4); +#endif +#endif +#endif +#endif + + map->c_keyhead = head; + map->create = 1; +} + + +#undef KEY1NAME +#undef KEY1TYPE +#undef KEY1_TYPE +#undef KEY1STOR + +#undef KEY2NAME +#undef KEY2TYPE +#undef KEY2_TYPE +#undef KEY2STOR + +#undef KEY3NAME +#undef KEY3TYPE +#undef KEY3_TYPE +#undef KEY3STOR + +#undef KEY4NAME +#undef KEY4TYPE +#undef KEY4_TYPE +#undef KEY4STOR + +#undef KEY5NAME +#undef KEY5TYPE +#undef KEY5_TYPE +#undef KEY5STOR + +#undef KEY_ARITY |