fast-stats 1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Makefile +23 -0
- data/ext/stats/.gitignore +12 -0
- data/ext/stats/error.c +42 -0
- data/ext/stats/extconf.rb +18 -0
- data/ext/stats/hash.c +66 -0
- data/ext/stats/lock.c +39 -0
- data/ext/stats/mt19937.c +209 -0
- data/ext/stats/mt19937.h +16 -0
- data/ext/stats/semaphore.c +278 -0
- data/ext/stats/shared_mem.c +238 -0
- data/ext/stats/stats/debug.h +8 -0
- data/ext/stats/stats/error.h +50 -0
- data/ext/stats/stats/hash.h +10 -0
- data/ext/stats/stats/lock.h +27 -0
- data/ext/stats/stats/omode.h +11 -0
- data/ext/stats/stats/semaphore.h +53 -0
- data/ext/stats/stats/shared_mem.h +46 -0
- data/ext/stats/stats/stats.h +215 -0
- data/ext/stats/stats-ruby.c +557 -0
- data/ext/stats/stats.c +597 -0
- data/ext/stats/strlcat.c +71 -0
- data/ext/stats/strlcpy.c +68 -0
- data/fast-stats.gemspec +17 -0
- data/lib/stats/version.rb +3 -0
- data/lib/stats.rb +8 -0
- data/test/benchmark_stats.rb +101 -0
- data/test/test_stats.rb +11 -0
- metadata +70 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
/* shared_mem.h */
|
2
|
+
|
3
|
+
#ifndef _SHARED_MEM_H_
|
4
|
+
#define _SHARED_MEM_H_
|
5
|
+
|
6
|
+
#include <sys/shm.h>
|
7
|
+
#include <sys/ipc.h>
|
8
|
+
|
9
|
+
#include "omode.h"
|
10
|
+
|
11
|
+
#define SHARED_MEMORY_MAGIC 'shmm'
|
12
|
+
|
13
|
+
#define DESTROY_ON_CLOSE 0x0000010
|
14
|
+
#define DESTROY_ON_CLOSE_IF_LAST 0x0000020
|
15
|
+
#define DESTROY_MASK 0x0000030
|
16
|
+
|
17
|
+
#define SHARED_MEMORY_MAX_NAME_LEN 31
|
18
|
+
|
19
|
+
struct shared_memory {
|
20
|
+
int magic;
|
21
|
+
int flags;
|
22
|
+
int size;
|
23
|
+
char name[SHARED_MEMORY_MAX_NAME_LEN + 1];
|
24
|
+
key_t shmkey;
|
25
|
+
int shmid;
|
26
|
+
short int created;
|
27
|
+
void * ptr;
|
28
|
+
};
|
29
|
+
|
30
|
+
int shared_memory_create(const char *name, int flags, int size, struct shared_memory **shmem_out);
|
31
|
+
int shared_memory_init(struct shared_memory *shmem, const char *name, int flags, int size);
|
32
|
+
int shared_memory_open(struct shared_memory *shmem);
|
33
|
+
int shared_memory_close(struct shared_memory *shmem, int* did_destroy);
|
34
|
+
void shared_memory_free(struct shared_memory *shmem);
|
35
|
+
int shared_memory_nattach(struct shared_memory *shmem, int *attach_count_out);
|
36
|
+
|
37
|
+
#define shared_memory_size(s) ((s)->size)
|
38
|
+
#define shared_memory_ptr(s) ((s)->ptr)
|
39
|
+
#define shared_memory_name(s) ((s)->name)
|
40
|
+
#define shared_memory_was_created(s) ((s)->created)
|
41
|
+
#define shared_memory_is_open(s) ((s)->shmid != -1 && (s)->ptr != NULL)
|
42
|
+
|
43
|
+
#define SHARED_MEMORY_DIRECTORY "/tmp"
|
44
|
+
#define MAX_PATH 255
|
45
|
+
|
46
|
+
#endif
|
@@ -0,0 +1,215 @@
|
|
1
|
+
/* stats.h */
|
2
|
+
|
3
|
+
#ifndef _STATS_H_INCLUDED_
|
4
|
+
#define _STATS_H_INCLUDED_
|
5
|
+
|
6
|
+
#include "shared_mem.h"
|
7
|
+
#include "lock.h"
|
8
|
+
|
9
|
+
#ifdef LINUX
|
10
|
+
size_t strlcat(char *dst, const char *src, size_t siz);
|
11
|
+
size_t strlcpy(char *dst, const char *src, size_t siz);
|
12
|
+
#endif
|
13
|
+
|
14
|
+
/* gets the current time as an absolute time */
|
15
|
+
long long current_time();
|
16
|
+
|
17
|
+
/* converts two absolute time to a difference in nanoseconds */
|
18
|
+
long long time_delta_to_nanos(long long start, long long end);
|
19
|
+
|
20
|
+
/* instead of using the above function, which may be a no-op, use the macro */
|
21
|
+
#ifdef DARWIN
|
22
|
+
#define TIME_DELTA_TO_NANOS(start,end) time_delta_to_nanos(start,end)
|
23
|
+
#endif
|
24
|
+
#ifdef LINUX
|
25
|
+
#define TIME_DELTA_TO_NANOS(start,end) (end-start)
|
26
|
+
#endif
|
27
|
+
|
28
|
+
#define STATS_MAX_NAME_LEN (SHARED_MEMORY_MAX_NAME_LEN - 4)
|
29
|
+
|
30
|
+
#define STATS_MAGIC 'stat'
|
31
|
+
|
32
|
+
|
33
|
+
typedef union {
|
34
|
+
long long val64;
|
35
|
+
struct {
|
36
|
+
int hi;
|
37
|
+
int lo;
|
38
|
+
} val32;
|
39
|
+
} STATS_VALUE;
|
40
|
+
|
41
|
+
|
42
|
+
/* stats_header is the first 16 bytes of the stats shared memory
|
43
|
+
*
|
44
|
+
* The stats_header should be aligned to a 16-byte boundary to
|
45
|
+
* preserve alignment of the stats counter data.
|
46
|
+
*
|
47
|
+
* stats_magic is the magic number STATS_MAGIC from above.
|
48
|
+
* stats_sequence_number is a value which starts at 0 and is incremented
|
49
|
+
* each time a new counter is allocated.
|
50
|
+
* reserved is there to align the structure to a multipe of 16 bytes.
|
51
|
+
*/
|
52
|
+
struct stats_header
|
53
|
+
{
|
54
|
+
int stats_magic;
|
55
|
+
int stats_sequence_number;
|
56
|
+
char reserved[8];
|
57
|
+
};
|
58
|
+
|
59
|
+
|
60
|
+
/* stats_counter is the data for each counter
|
61
|
+
*
|
62
|
+
* The stats_counter should be a multiple of 8 bytes to preserve
|
63
|
+
* alignment. The current definition is 56 bytes.
|
64
|
+
*
|
65
|
+
* ctr_allocation_status is a flag indicating if the counter is
|
66
|
+
* in use or not.
|
67
|
+
* ctr_allocation_seq is an ordinal indicationg the order which
|
68
|
+
* the counter was allocated. When you get a counter list
|
69
|
+
* the pointers will be sorted according to this ordinal so
|
70
|
+
* every list is in the same order, with new counters sorted
|
71
|
+
* to the end.
|
72
|
+
* ctr_value is the value of the counter (either 64 or 32 bits)
|
73
|
+
* ctr_flags indicates the type of counter (timer, gauge) and the
|
74
|
+
* size of the counter (64 or 32 bits)
|
75
|
+
* ctr_key_len indicates the number of characters in ctr_key which
|
76
|
+
* make up the counter name
|
77
|
+
* ctr_key contains the name of the counter. Note: this string may
|
78
|
+
* not be NUL terminated. If ctr_key_len == MAX_COUNTER_KEY_LENGTH
|
79
|
+
* then there will NOT be a NUL char at the end of the string.
|
80
|
+
* The safest thing to do is to use counter_get_key() to get
|
81
|
+
* the name, which will return a NUL terminated string.
|
82
|
+
*/
|
83
|
+
|
84
|
+
#define MAX_COUNTER_KEY_LENGTH 32
|
85
|
+
|
86
|
+
/* flags for the ctr_allocation_status field */
|
87
|
+
#define ALLOCATION_STATUS_FREE 0
|
88
|
+
#define ALLOCATION_STATUS_CLAIMED -1 /* not used right now */
|
89
|
+
#define ALLOCATION_STATUS_ALLOCATED 1
|
90
|
+
|
91
|
+
|
92
|
+
/* flags for the ctr_flags field */
|
93
|
+
#define CTR_FLAG_32BIT 0x00000000
|
94
|
+
#define CTR_FLAG_64BIT 0x00000001
|
95
|
+
|
96
|
+
#define CTR_FLAG_TIMER 0x00000010
|
97
|
+
#define CTR_FLAG_GAUGE 0x00000020
|
98
|
+
|
99
|
+
struct stats_counter
|
100
|
+
{
|
101
|
+
int ctr_allocation_status;
|
102
|
+
int ctr_allocation_seq;
|
103
|
+
STATS_VALUE ctr_value;
|
104
|
+
int ctr_flags;
|
105
|
+
int ctr_key_len;
|
106
|
+
char ctr_key[MAX_COUNTER_KEY_LENGTH];
|
107
|
+
};
|
108
|
+
|
109
|
+
|
110
|
+
/* stats_data is the layout of the shared memory data.
|
111
|
+
*
|
112
|
+
* It contains a header followed by a fixed size hash table
|
113
|
+
* containing the counters.
|
114
|
+
*
|
115
|
+
* The size of the hash table should be a prime number for better
|
116
|
+
* hashing. Right now, we are using 2003, which is the smallest
|
117
|
+
* prime number larger than 2000. This is a compile-time setting
|
118
|
+
* and can be changed to any other prime number.
|
119
|
+
*/
|
120
|
+
|
121
|
+
#define COUNTER_TABLE_SIZE 2003
|
122
|
+
|
123
|
+
struct stats_data
|
124
|
+
{
|
125
|
+
struct stats_header hdr;
|
126
|
+
struct stats_counter ctr[COUNTER_TABLE_SIZE];
|
127
|
+
};
|
128
|
+
|
129
|
+
|
130
|
+
/* struct stats
|
131
|
+
*
|
132
|
+
* the in-memory stats object
|
133
|
+
*/
|
134
|
+
|
135
|
+
struct stats
|
136
|
+
{
|
137
|
+
int magic;
|
138
|
+
struct shared_memory shmem;
|
139
|
+
struct lock lock;
|
140
|
+
struct stats_data *data;
|
141
|
+
};
|
142
|
+
|
143
|
+
int stats_create(const char *name, struct stats **stats_out);
|
144
|
+
int stats_open(struct stats *stats);
|
145
|
+
int stats_close(struct stats *stats);
|
146
|
+
int stats_free(struct stats *stats);
|
147
|
+
|
148
|
+
int stats_allocate_counter(struct stats *stats, const char *name, struct stats_counter **ctr_out);
|
149
|
+
|
150
|
+
/* clear all of the counters in the structure to 0 */
|
151
|
+
int stats_reset_counters(struct stats *stats);
|
152
|
+
|
153
|
+
/* deprecated. use stats_counter_list instead */
|
154
|
+
int stats_get_counters(struct stats *stats, struct stats_counter **counters, int counter_size, int *counter_out, int *sequence_number_out);
|
155
|
+
|
156
|
+
|
157
|
+
/**
|
158
|
+
* stats_counter_list
|
159
|
+
*
|
160
|
+
* stats_counter_list contains a snapshot of the set of counters in the shared
|
161
|
+
* memory at a point in time.
|
162
|
+
*
|
163
|
+
* cl_seq_no - represents the point in time which this counter list represents
|
164
|
+
* this value is copied from the stats.stats_sequence_number at the time
|
165
|
+
* the counter list is captured.
|
166
|
+
* cl_count - the number of counters in cl_ctr
|
167
|
+
* cl_ctr - a contiguous array of pointers to stats_counter objects
|
168
|
+
* from [0,cl_count-1]
|
169
|
+
*/
|
170
|
+
|
171
|
+
struct stats_counter_list
|
172
|
+
{
|
173
|
+
int cl_seq_no;
|
174
|
+
int cl_count;
|
175
|
+
struct stats_counter *cl_ctr[COUNTER_TABLE_SIZE];
|
176
|
+
};
|
177
|
+
|
178
|
+
int stats_get_counter_list(struct stats *stats, struct stats_counter_list *cl);
|
179
|
+
int stats_cl_create(struct stats_counter_list **cl_out);
|
180
|
+
void stats_cl_init(struct stats_counter_list *cl);
|
181
|
+
void stats_cl_free(struct stats_counter_list *cl);
|
182
|
+
int stats_cl_is_updated(struct stats *stats, struct stats_counter_list *cl);
|
183
|
+
|
184
|
+
|
185
|
+
/**
|
186
|
+
* stats_sample
|
187
|
+
*/
|
188
|
+
|
189
|
+
struct stats_sample
|
190
|
+
{
|
191
|
+
int sample_seq_no;
|
192
|
+
int sample_count;
|
193
|
+
long long sample_time;
|
194
|
+
STATS_VALUE sample_value[COUNTER_TABLE_SIZE];
|
195
|
+
};
|
196
|
+
|
197
|
+
int stats_sample_create(struct stats_sample **sample_out);
|
198
|
+
void stats_sample_init(struct stats_sample *sample);
|
199
|
+
void stats_sample_free(struct stats_sample *sample);
|
200
|
+
long long stats_sample_get_value(struct stats_sample *sample, int index);
|
201
|
+
long long stats_sample_get_delta(struct stats_sample *sample, struct stats_sample *prev_sample, int index);
|
202
|
+
|
203
|
+
int stats_get_sample(struct stats *stats, struct stats_counter_list *cl, struct stats_sample *sample);
|
204
|
+
|
205
|
+
|
206
|
+
|
207
|
+
void counter_get_key(struct stats_counter *ctr, char *buf, int buflen);
|
208
|
+
void counter_increment(struct stats_counter *ctr);
|
209
|
+
void counter_increment_by(struct stats_counter *ctr, long long val);
|
210
|
+
void counter_clear(struct stats_counter *ctr);
|
211
|
+
void counter_set(struct stats_counter *ctr, long long val);
|
212
|
+
|
213
|
+
#define stats_get_sequence_number(s) ((s)->data->hdr.stats_sequence_number)
|
214
|
+
|
215
|
+
#endif
|