summaryrefslogtreecommitdiffstats
path: root/runtime/map.h
blob: 019da3d0a8ba3baa483d4936cd5af777902d2230 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* -*- linux-c -*- */
/** @file map.h
 * @brief Header file for maps and lists
 */

#include <linux/types.h>

/** Statistics are stored in this struct
*/
typedef struct {
	int64_t count;
	int64_t sum;
	int64_t min, max;
	int64_t histogram[BUCKETS];
} stat;

/** Keys are either longs or char *
 */
union key_data {
	long val;
	char *str;
};

enum keytype { NONE, LONG, STR } __attribute__ ((packed));
enum valtype { INT64, STAT, STRING, END };

/** all map nodes have the following structure 
*/
struct map_node {
	struct list_head lnode;
	struct hlist_node hnode;
	union key_data key1;
	union key_data key2;
	enum keytype key1type;
	enum keytype key2type;
};

/* specific map nodes with data attached */
struct map_node_int64 {
	struct map_node n;
	int64_t val;
};

struct map_node_str {
	struct map_node n;
	char *str;
};

struct map_node_stat {
	struct map_node n;
	stat stats;
};

/** This structure contains all information about a map.
 * It is allocated once when _stp_map_new() is called.
 */
struct map_root {
	enum valtype type;  /** type of the values stored in the array */
	int maxnum; 	/** maximum number of elements allowed in the array. */

	/* current number of elements */
	int num;

	/* when more than maxnum elements, wrap or discard */
	int no_wrap;

	/* linked list of current entries */
	struct list_head head;

	/* pool of unused entries.  Used only when entries are statically allocated */
	/* at startup. */
	struct list_head pool;

	/* saved key entry for lookups */
	struct map_node *key;

	/* this is the creation data saved between the key functions and the */
	/* set/get functions */
	u_int8_t create;
	enum keytype c_key1type;
	enum keytype c_key2type;
	struct hlist_head *c_keyhead;
	union key_data c_key1;
	union key_data c_key2;

	/* the hash table for this array */
	struct hlist_head hashes[HASH_TABLE_SIZE];

	/* pointer to allocated memory space */
	void *membuf;
};

/** All maps are of this type.
 */
typedef struct map_root *MAP;

#define key1str(ptr) (ptr->n.key1.str)
#define key2str(ptr) (ptr->n.key2.str)
#define key1int(ptr) (ptr->n.key1.val)
#define key2int(ptr) (ptr->n.key2.val)

#define _stp_map_key2(map, key1, key2)				\
  ({								\
    if (__builtin_types_compatible_p (typeof (key1), char[]))	\
      if (__builtin_types_compatible_p (typeof (key2), char[])) \
	_stp_map_key_str_str (map, (char *)(key1), (char *)(key2));	\
      else							\
	_stp_map_key_str_long (map, (char *)(key1), (long)(key2));	\
    else							\
      if (__builtin_types_compatible_p (typeof (key2), char[])) \
	_stp_map_key_long_str (map, (long)(key1), (char *)(key2));	\
      else							\
	_stp_map_key_long_long (map, (long)(key1), (long)(key2));	\
  })

#define _stp_map_key(map, key)				\
  ({								\
    if (__builtin_types_compatible_p (typeof (key), char[]))	\
      _stp_map_key_str (map, (char *)(key));				\
    else							\
      _stp_map_key_long (map, (long)(key));				\
  })

#define _stp_map_set(map, val)				\
  ({								\
    if (__builtin_types_compatible_p (typeof (val), char[]))	\
      _stp_map_set_str (map, (char *)(val));				\
    else							\
      _stp_map_set_int64 (map, (int64_t)(val));			\
  })

#define _stp_list_add(map, val)				\
  ({								\
    if (__builtin_types_compatible_p (typeof (val), char[]))	\
      _stp_list_add_str (map, (char *)(val));				\
    else							\
      _stp_list_add_int64 (map, (int64_t)(val));			\
  })


/** Loop through all elements of a map.
 * @param map 
 * @param ptr pointer to a map_node_stat, map_node_int64 or map_node_str
 *
 * @b Example:
 * @include foreach.c
 */

#define foreach(map, ptr)				\
  for (ptr = (typeof(ptr))_stp_map_start(map); ptr; \
       ptr = (typeof(ptr))_stp_map_iter (map, (struct map_node *)ptr))