"Fossies" - the Fresh Open Source Software Archive 
Member "memcached-1.6.15/stats_prefix.c" (21 Feb 2022, 4441 Bytes) of package /linux/www/memcached-1.6.15.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "stats_prefix.c" see the
Fossies "Dox" file reference documentation.
1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* Author: Steven Grimm <sgrimm@facebook.com> */
3 #include "memcached.h"
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <assert.h>
8
9 /* Hash table that uses the global hash function */
10 static PREFIX_STATS *prefix_stats[PREFIX_HASH_SIZE];
11
12 static char prefix_delimiter;
13 static int num_prefixes = 0;
14 static int total_prefix_size = 0;
15
16 void stats_prefix_init(char delimiter) {
17 prefix_delimiter = delimiter;
18 memset(prefix_stats, 0, sizeof(prefix_stats));
19 }
20
21 void stats_prefix_clear(void) {
22 int i;
23
24 for (i = 0; i < PREFIX_HASH_SIZE; i++) {
25 PREFIX_STATS *cur, *next;
26 for (cur = prefix_stats[i]; cur != NULL; cur = next) {
27 next = cur->next;
28 free(cur->prefix);
29 free(cur);
30 }
31 prefix_stats[i] = NULL;
32 }
33 num_prefixes = 0;
34 total_prefix_size = 0;
35 }
36
37 PREFIX_STATS *stats_prefix_find(const char *key, const size_t nkey) {
38 PREFIX_STATS *pfs;
39 uint32_t hashval;
40 size_t length;
41 bool bailout = true;
42
43 assert(key != NULL);
44
45 for (length = 0; length < nkey && key[length] != '\0'; length++) {
46 if (key[length] == prefix_delimiter) {
47 bailout = false;
48 break;
49 }
50 }
51
52 if (bailout) {
53 return NULL;
54 }
55
56 hashval = hash(key, length) % PREFIX_HASH_SIZE;
57
58 for (pfs = prefix_stats[hashval]; NULL != pfs; pfs = pfs->next) {
59 if (strncmp(pfs->prefix, key, length) == 0)
60 return pfs;
61 }
62
63 pfs = calloc(sizeof(PREFIX_STATS), 1);
64 if (NULL == pfs) {
65 perror("Can't allocate space for stats structure: calloc");
66 return NULL;
67 }
68
69 pfs->prefix = malloc(length + 1);
70 if (NULL == pfs->prefix) {
71 perror("Can't allocate space for copy of prefix: malloc");
72 free(pfs);
73 return NULL;
74 }
75
76 strncpy(pfs->prefix, key, length);
77 pfs->prefix[length] = '\0'; /* because strncpy() sucks */
78 pfs->prefix_len = length;
79
80 pfs->next = prefix_stats[hashval];
81 prefix_stats[hashval] = pfs;
82
83 num_prefixes++;
84 total_prefix_size += length;
85
86 return pfs;
87 }
88
89 void stats_prefix_record_get(const char *key, const size_t nkey, const bool is_hit) {
90 PREFIX_STATS *pfs;
91
92 STATS_LOCK();
93 pfs = stats_prefix_find(key, nkey);
94 if (NULL != pfs) {
95 pfs->num_gets++;
96 if (is_hit) {
97 pfs->num_hits++;
98 }
99 }
100 STATS_UNLOCK();
101 }
102
103 void stats_prefix_record_delete(const char *key, const size_t nkey) {
104 PREFIX_STATS *pfs;
105
106 STATS_LOCK();
107 pfs = stats_prefix_find(key, nkey);
108 if (NULL != pfs) {
109 pfs->num_deletes++;
110 }
111 STATS_UNLOCK();
112 }
113
114 void stats_prefix_record_set(const char *key, const size_t nkey) {
115 PREFIX_STATS *pfs;
116
117 STATS_LOCK();
118 pfs = stats_prefix_find(key, nkey);
119 if (NULL != pfs) {
120 pfs->num_sets++;
121 }
122 STATS_UNLOCK();
123 }
124
125 char *stats_prefix_dump(int *length) {
126 const char *format = "PREFIX %s get %llu hit %llu set %llu del %llu\r\n";
127 PREFIX_STATS *pfs;
128 char *buf;
129 int i, pos;
130 size_t size = 0, written = 0;
131 #ifndef NDEBUG
132 size_t total_written = 0;
133 #endif
134 /*
135 * Figure out how big the buffer needs to be. This is the sum of the
136 * lengths of the prefixes themselves, plus the size of one copy of
137 * the per-prefix output with 20-digit values for all the counts,
138 * plus space for the "END" at the end.
139 */
140 STATS_LOCK();
141 size = strlen(format) + total_prefix_size +
142 num_prefixes * (strlen(format) - 2 /* %s */
143 + 4 * (20 - 4)) /* %llu replaced by 20-digit num */
144 + sizeof("END\r\n");
145 buf = malloc(size);
146 if (NULL == buf) {
147 perror("Can't allocate stats response: malloc");
148 STATS_UNLOCK();
149 return NULL;
150 }
151
152 pos = 0;
153 for (i = 0; i < PREFIX_HASH_SIZE; i++) {
154 for (pfs = prefix_stats[i]; NULL != pfs; pfs = pfs->next) {
155 written = snprintf(buf + pos, size-pos, format,
156 pfs->prefix, pfs->num_gets, pfs->num_hits,
157 pfs->num_sets, pfs->num_deletes);
158 pos += written;
159 #ifndef NDEBUG
160 total_written += written;
161 assert(total_written < size);
162 #endif
163 }
164 }
165
166 STATS_UNLOCK();
167 memcpy(buf + pos, "END\r\n", 6);
168
169 *length = pos + 5;
170 return buf;
171 }