diff options
Diffstat (limited to 'runtime/map.c')
-rw-r--r-- | runtime/map.c | 429 |
1 files changed, 62 insertions, 367 deletions
diff --git a/runtime/map.c b/runtime/map.c index 98ed6af9..187a1872 100644 --- a/runtime/map.c +++ b/runtime/map.c @@ -28,120 +28,8 @@ int int64_eq_p (int64_t key1, int64_t key2) #endif /* NEED_INT64_KEYS */ -#ifdef NEED_INT64_VALS -void int64_copy (void *dest, int64_t val) -{ - *(int64_t *)dest = val; -} - -void int64_add (void *dest, int64_t val) -{ - *(int64_t *)dest += val; -} - -int64_t int64_get (void *ptr) -{ - return *(int64_t *)ptr; -} -#endif /* NEED_INT64_VALS */ - -#ifdef NEED_STAT_VALS -void stat_copy (void *dest, stat *src) -{ - memcpy (dest, src, sizeof(stat)); -} - -void stat_add (void *dest, stat *src) -{ - stat *d = (stat *)dest; - - d->count =+ src->count; - d->sum += src->sum; - if (src->max > d->max) - d->max = src->max; - if (src->min < d->min) - d->min = src->min; - /* FIXME: do histogram */ -} - -stat *stat_get(void *ptr) -{ - return (stat *)ptr; -} - -/* implements a log base 2 function, or Most Significant Bit */ -/* with bits from 1 (lsb) to 64 (msb) */ -/* msb64(0) = 0 */ -/* msb64(1) = 1 */ -/* msb64(8) = 4 */ -/* msb64(512) = 10 */ - -int msb64(int64_t val) -{ - int res = 64; - - if (val == 0) - return 0; - - /* shortcut. most values will be 16-bit */ - if (val & 0xffffffffffff0000ull) { - if (!(val & 0xffffffff00000000ull)) { - val <<= 32; - res -= 32; - } - - if (!(val & 0xffff000000000000ull)) { - val <<= 16; - res -= 16; - } - } else { - val <<= 48; - res -= 48; - } - - if (!(val & 0xff00000000000000ull)) { - val <<= 8; - res -= 8; - } - - if (!(val & 0xf000000000000000ull)) { - val <<= 4; - res -= 4; - } - - if (!(val & 0xc000000000000000ull)) { - val <<= 2; - res -= 2; - } - - if (!(val & 0x8000000000000000ull)) { - val <<= 1; - res -= 1; - } - - return res; -} - -#endif /* NEED_STAT_VALS */ - -int64_t _stp_key_get_int64 (struct map_node *mn, int n) -{ - if (mn) - return (*mn->map->get_key)(mn, n, NULL).val; - return 0; -} - -char *_stp_key_get_str (struct map_node *mn, int n) -{ - if (mn) - return (*mn->map->get_key)(mn, n, NULL).strp; - return ""; -} - - - -#if defined(NEED_STRING_VALS) || defined (NEED_STRING_KEYS) +#if defined (NEED_STRING_KEYS) || defined (NEED_STRING_VALS) void str_copy(char *dest, char *src) { int len = strlen(src); @@ -152,43 +40,6 @@ void str_copy(char *dest, char *src) } #endif -#ifdef NEED_STRING_VALS -void str_add(void *dest, char *val) -{ - char *dst = (char *)dest; - int len = strlen(val); - int len1 = strlen(dst); - int num = MAP_STRING_LENGTH - 1 - len1; - - if (len > num) - len = num; - strncpy (&dst[len1], val, len); - dst[len + len1] = 0; -} - -char *str_get (void *ptr) -{ - return ptr; -} - -/** Set the current element's value to String. - * This sets the current element's value to a String. The map must have been created - * to hold int64s using <i>_stp_map_new(xxx, STRING)</i> - * - * If the element doesn't exist, it is created. If no current element (key) - * is set for the map, this function does nothing. - * @param map - * @param str String containing new value. - * @sa _stp_map_set() - */ - -void _stp_map_set_string (MAP map, String str) -{ - _stp_map_set_str (map, str->buf); -} - -#endif /* NEED_STRING_VALS */ - #ifdef NEED_STRING_KEYS int str_eq_p (char *key1, char *key2) { @@ -206,26 +57,74 @@ unsigned int str_hash(const char *key1) } #endif /* NEED_STRING_KEYS */ +/** @addtogroup maps + * Implements maps (associative arrays) and lists + * @{ + */ + +/** Return an int64 from a map node. + * This function will return the int64 value of a map_node + * from a map containing int64s. You can get the map_nodes in a map + * with _stp_map_start(), _stp_map_iter() and foreach(). + * @param m pointer to the map_node. + * @returns an int64 value. + */ int64_t _stp_get_int64(struct map_node *m) { return *(int64_t *)((long)m + m->map->data_offset); } +/** Return a string from a map node. + * This function will return the string value of a map_node + * from a map containing strings. You can get the map_nodes in a map + * with _stp_map_start(), _stp_map_iter() and foreach(). + * @param m pointer to the map_node. + * @returns a pointer to a string. + */ char *_stp_get_str(struct map_node *m) { return (char *)((long)m + m->map->data_offset); } +/** Return a stat pointer from a map node. + * This function will return the stats of a map_node + * from a map containing stats. You can get the map_nodes in a map + * with _stp_map_start(), _stp_map_iter() and foreach(). + * @param m pointer to the map_node. + * @returns A pointer to the stats. + */ stat *_stp_get_stat(struct map_node *m) { return (stat *)((long)m + m->map->data_offset); } +/** Return an int64 key from a map node. + * This function will return an int64 key from a map_node. + * @param m pointer to the map_node. + * @param n key number + * @returns an int64 + * @sa key1int(), key2int() + */ +int64_t _stp_key_get_int64 (struct map_node *mn, int n) +{ + if (mn) + return (*mn->map->get_key)(mn, n, NULL).val; + return 0; +} -/** @addtogroup maps - * Implements maps (associative arrays) and lists - * @{ +/** Return a string key from a map node. + * This function will return an string key from a map_node. + * @param m pointer to the map_node. + * @param n key number + * @returns a pointer to a string + * @sa key1str(), key2str() */ +char *_stp_key_get_str (struct map_node *mn, int n) +{ + if (mn) + return (*mn->map->get_key)(mn, n, NULL).strp; + return ""; +} /** Create a new map. * Maps must be created at module initialization time. @@ -235,6 +134,7 @@ stat *_stp_get_stat(struct map_node *m) * will be allocated dynamically. * @param type Type of values stored in this map. * @return A MAP on success or NULL on failure. + * @ingroup map_create */ static MAP _stp_map_new(unsigned max_entries, int type, int key_size, int data_size) @@ -283,49 +183,6 @@ static MAP _stp_map_new(unsigned max_entries, int type, int key_size, int data_s return m; } -MAP _stp_map_new_hstat_log (unsigned max_entries, int key_size, int buckets) -{ - /* add size for buckets */ - int size = buckets * sizeof(int64_t) + sizeof(stat); - MAP m = _stp_map_new (max_entries, STAT, key_size, size); - if (m) { - m->hist_type = HIST_LOG; - m->hist_buckets = buckets; - if (buckets < 1 || buckets > 64) { - dbug ("histogram: Bad number of buckets. Must be between 1 and 64\n"); - m->hist_type = HIST_NONE; - return m; - } - } - return m; -} - -MAP _stp_map_new_hstat_linear (unsigned max_entries, int ksize, int start, int stop, int interval) -{ - MAP m; - int size; - int buckets = (stop - start) / interval; - if ((stop - start) % interval) buckets++; - - /* add size for buckets */ - size = buckets * sizeof(int64_t) + sizeof(stat); - - m = _stp_map_new (max_entries, STAT, ksize, size); - if (m) { - m->hist_type = HIST_LINEAR; - m->hist_start = start; - m->hist_stop = stop; - m->hist_int = interval; - m->hist_buckets = buckets; - if (m->hist_buckets <= 0) { - dbug ("histogram: bad stop, start and/or interval\n"); - m->hist_type = HIST_NONE; - return m; - } - - } - return m; -} /** Deletes the current element. * If no current element (key) for this map is set, this function does nothing. @@ -421,150 +278,6 @@ void _stp_map_del(MAP map) _stp_vfree(map); } -#ifdef NEED_STAT_VALS - -static int needed_space(int64_t v) -{ - int space = 0; - - if (v == 0) - return 1; - - if (v < 0) { - space++; - v = -v; - } - while (v) { - /* v /= 10; */ - do_div (v, 10); - space++; - } - return space; -} - -static void reprint (int num, char *s) -{ - while (num > 0) { - _stp_print_cstr (s); - num--; - } -} - -#define HIST_WIDTH 50 - -void _stp_map_print_histogram (MAP map, stat *s) -{ - int scale, i, j, val_space, cnt_space; - int64_t val, v, max = 0; - - if (map->hist_type != HIST_LOG && map->hist_type != HIST_LINEAR) - return; - /* get the maximum value, for scaling */ - - for (i = 0; i < map->hist_buckets; i++) - if (s->histogram[i] > max) - max = s->histogram[i]; - - if (max <= HIST_WIDTH) - scale = 1; - else { - int64_t tmp = max; - int rem = do_div (tmp, HIST_WIDTH); - scale = tmp; - if (rem) scale++; - } - - cnt_space = needed_space (max); - if (map->hist_type == HIST_LINEAR) - val_space = needed_space (map->hist_start + map->hist_int * (map->hist_buckets - 1)); - else - val_space = needed_space (1 << (map->hist_buckets - 1)); - dbug ("max=%lld scale=%d val_space=%d\n", max, scale, val_space); - - /* print header */ - j = 0; - if (val_space > 5) /* 5 = sizeof("value") */ - j = val_space - 5; - else - val_space = 5; - for ( i = 0; i < j; i++) - _stp_print_cstr (" "); - _stp_print_cstr("value |"); - reprint (HIST_WIDTH, "-"); - _stp_print_cstr (" count\n"); - _stp_print_flush(); - if (map->hist_type == HIST_LINEAR) - val = map->hist_start; - else - val = 0; - for (i = 0; i < map->hist_buckets; i++) { - reprint (val_space - needed_space(val), " "); - _stp_printf("%d", val); - _stp_print_cstr (" |"); - - /* v = s->histogram[i] / scale; */ - v = s->histogram[i]; - do_div (v, scale); - - reprint (v, "@"); - reprint (HIST_WIDTH - v + 1 + cnt_space - needed_space(s->histogram[i]), " "); - _stp_printf ("%lld\n", s->histogram[i]); - if (map->hist_type == HIST_LINEAR) - val += map->hist_int; - else if (val == 0) - val = 1; - else - val *= 2; - } -} -#endif /* NEED_STAT_VALS */ - -/* Print stuff until a format specification is found. */ -/* Return pointer to that. */ -static char *next_fmt(char *fmt, int *num) -{ - char *f = fmt; - int in_fmt = 0; - dbug ("next_fmt %s\n", fmt); - *num = 0; - while (*f) { - if (in_fmt) { - if (*f == '%') { - _stp_string_cat_char(_stp_stdout,'%'); - in_fmt = 0; - } else if (*f > '0' && *f <= '9') { - *num = *f - '0'; - f++; - return f; - } else - return f; - } else if (*f == '%') - in_fmt = 1; - else - _stp_string_cat_char(_stp_stdout,*f); - f++; - } - return f; -} - -/* print type based on format. Valid formats are: ---- KEYS and RESULTS --- -%p - address (hex padded to sizeof(void *)) -%P - symbolic address -%x - hex int64 -%X - HEX int64 -%d - decimal int64 -%s - string ---- STATS --- -%m - min -%M - max -%A - avg -%S - sum -%H - histogram -%C - count ---- MISC --- -%% - print '%' -*/ static int print_keytype (char *fmt, int type, key_data *kd) { dbug ("*fmt = %c\n", *fmt); @@ -628,41 +341,23 @@ static void print_valtype (MAP map, char *fmt, struct map_node *ptr) #ifdef NEED_STAT_VALS case STAT: { - stat *s = _stp_get_stat(ptr); - switch (*fmt) { - case 'C': - _stp_printf("%lld", s->count); - break; - case 'm': - _stp_printf("%lld", s->min); - break; - case 'M': - _stp_printf("%lld", s->max); - break; - case 'S': - _stp_printf("%lld", s->sum); - break; - case 'A': - { - int64_t avg = s->sum; - do_div (avg, (int)s->count); /* FIXME: check for overflow */ - _stp_printf("%lld", avg); - break; - } - case 'H': - _stp_map_print_histogram (map, s); - _stp_print_flush(); - break; - } + Stat st = (Stat)((long)map + offsetof(struct map_root, hist_type)); + stat *sd = _stp_get_stat(ptr); + _stp_stat_print_valtype (fmt, st, sd, 0); break; } - #endif default: break; } } +/** Print a Map. + * Print a Map using a format string. + * + * @param map Map + * @param fmt @ref format_string + */ void _stp_map_print (MAP map, const char *fmt) { struct map_node *ptr; |