Skip to content

Commit 8b997d7

Browse files
code tag
1 parent 42d796a commit 8b997d7

File tree

6 files changed

+650
-98
lines changed

6 files changed

+650
-98
lines changed

cmd_in_second.c

Lines changed: 101 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -10,66 +10,69 @@
1010
#include <stdlib.h>
1111
#include <fcntl.h>
1212

13-
#define LOG_PER_TIMER 500
1413
#define LOG_LENGTH 400
1514
#define IP_LENGTH 16
1615
#define KEY_LENGTH 256
1716

18-
typedef enum cmd_in_second_state{
17+
typedef enum cmd_in_second_state {
1918
NOT_STARTED,
2019
ON_LOGGING,
2120
ON_FLUSHING
22-
}state;
21+
} state;
2322

24-
typedef struct cmd_in_second_log{
23+
typedef struct cmd_in_second_log {
2524
char key[KEY_LENGTH];
2625
char client_ip[IP_LENGTH];
27-
int32_t timer_idx;
28-
}logtype;
26+
} logtype;
2927

3028
typedef struct cmd_in_second_buffer {
3129
logtype *ring;
3230
int32_t front;
3331
int32_t rear;
3432
int32_t capacity;
35-
}buffertype;
33+
} buffertype;
3634

37-
typedef struct cmd_in_second_timer{
38-
struct timeval* times;
39-
int32_t size;
40-
int32_t counter;
41-
}timertype;
35+
typedef struct cmd_in_second_timer {
36+
struct timeval* ring;
37+
int32_t front;
38+
int32_t rear;
39+
int32_t capacity;
40+
int32_t circular_counter;
41+
} timertype;
4242

4343
struct cmd_in_second {
44-
char cmd[10];
45-
char collection_name[4];
44+
char cmd[20];
45+
char collection_name[10];
4646
struct cmd_in_second_buffer buffer;
47-
int32_t bulk_limit;
4847
timertype timer;
48+
int32_t bulk_limit;
49+
int32_t log_per_timer;
4950
state cur_state;
5051
};
5152

52-
static EXTENSION_LOGGER_DESCRIPTOR *mc_logger;
5353
static struct cmd_in_second this;
5454

5555
static bool is_bulk_cmd()
5656
{
57-
const logtype* front = &this.buffer.ring[this.buffer.front];
58-
const logtype* rear = &this.buffer.ring[this.buffer.rear];
57+
const bool timer_empty = this.timer.front == this.timer.rear;
5958

60-
struct timeval front_time = this.timer.times[front->timer_idx];
61-
struct timeval rear_time = this.timer.times[rear->timer_idx];
59+
if (timer_empty) {
60+
return false;
61+
}
62+
63+
const struct timeval *front_time = &this.timer.ring[this.timer.front];
64+
const struct timeval *rear_time = &this.timer.ring[this.timer.rear];
6265

63-
return rear_time.tv_sec - front_time.tv_sec <= 1;
66+
return rear_time->tv_sec - front_time->tv_sec <= 1;
6467
}
6568

6669
static void get_whole_cmd(char* whole_cmd)
6770
{
6871
if (strlen(this.collection_name)) {
69-
sprintf(whole_cmd, "%s %s", this.collection_name, this.cmd);
72+
snprintf(whole_cmd, 20, "%s %s", this.collection_name, this.cmd);
7073
return;
7174
}
72-
sprintf(whole_cmd, "%s", this.cmd);
75+
snprintf(whole_cmd, 15, "%s", this.cmd);
7376
}
7477

7578
static bool buffer_empty()
@@ -79,64 +82,74 @@ static bool buffer_empty()
7982

8083
static void* buffer_flush_thread()
8184
{
82-
int32_t fd = open("cmd_in_second.log", O_CREAT | O_WRONLY | O_TRUNC, 0644);
85+
const int32_t fd = open("cmd_in_second.log", O_CREAT | O_WRONLY | O_TRUNC, 0644);
8386

8487
if (fd < 0) {
85-
mc_logger->log(EXTENSION_LOG_WARNING, NULL,
86-
"Can't open cmd_in_second log file: %s\n", "cmd_in_second.log");
88+
perror("Can't open cmd_in_second log file: cmd_in_second.log");
8789
return NULL;
8890
}
8991

90-
char whole_cmd[20] = "";
91-
get_whole_cmd(whole_cmd);
92-
9392
buffertype* buffer = &this.buffer;
9493
timertype* timer = &this.timer;
9594

96-
int32_t timer_idx = -1;
97-
9895
char* log_str = (char*)malloc(LOG_LENGTH * this.bulk_limit * sizeof(char));
9996

10097
if (log_str == NULL) {
101-
mc_logger->log(EXTENSION_LOG_WARNING, NULL, "Can't allocate memory");
98+
perror("Can't allocate memory");
10299
return NULL;
103100
}
104101

105-
int32_t expected_write_length = 0;
102+
char whole_cmd[20] = "";
103+
get_whole_cmd(whole_cmd);
104+
105+
const size_t whole_cmd_len = strlen(whole_cmd);
106+
const int32_t whitespaces = 3;
107+
108+
size_t expected_write_length = 0;
109+
int32_t circular_log_counter = 0;
106110

107111
while (!buffer_empty()) {
108112

109-
logtype front = buffer->ring[buffer->front++];
113+
const logtype front = buffer->ring[buffer->front];
114+
buffer->front = (buffer->front+1) % buffer->capacity;
110115

111116
char time_str[50] = "";
112117

113-
if (front.timer_idx != timer_idx) {
118+
if (circular_log_counter == 0) {
114119

115-
const struct timeval* front_time = &timer->times[front.timer_idx];
120+
const struct timeval* front_time = &timer->ring[timer->front];
116121
const struct tm *lt = localtime((time_t*)&front_time->tv_sec);
117122

118-
sprintf(time_str, "%04d-%02d-%02d %02d:%02d:%02d.%06d\n", lt ->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, (int32_t)front_time->tv_usec);
119-
timer_idx = front.timer_idx;
123+
timer->front = (timer->front+1) % timer->capacity;
124+
125+
if (lt == NULL) {
126+
perror("localtime failed");
127+
continue;
128+
}
120129

130+
sprintf(time_str, "%04d-%02d-%02d %02d:%02d:%02d.%06d\n", lt ->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday,
131+
lt->tm_hour, lt->tm_min, lt->tm_sec, (int32_t)front_time->tv_usec);
121132
expected_write_length += 27;
122133
}
134+
123135
char log[LOG_LENGTH] = "";
124-
sprintf(log, "%s%s %s %s\n", time_str, whole_cmd, front.key, front.client_ip);
136+
snprintf(log, LOG_LENGTH, "%s%s %s %s\n", time_str, whole_cmd, front.key, front.client_ip);
125137
strncat(log_str, log, LOG_LENGTH);
126138

127-
expected_write_length += LOG_LENGTH;
139+
expected_write_length += whole_cmd_len + strlen(front.key) + strlen(front.client_ip) + whitespaces;
140+
circular_log_counter = (circular_log_counter+1) % this.log_per_timer;
128141
}
129142

130143
if (write(fd, log_str, expected_write_length) != expected_write_length) {
131-
mc_logger->log(EXTENSION_LOG_WARNING, NULL, "write length is difference to expectation.");
144+
perror("write length is difference to expectation.");
132145
}
133146

134147
close(fd);
135148

136149
free(log_str);
137150

138-
free(this.timer.times);
139-
this.timer.times = NULL;
151+
free(this.timer.ring);
152+
this.timer.ring = NULL;
140153

141154
free(this.buffer.ring);
142155
this.buffer.ring = NULL;
@@ -148,19 +161,19 @@ static void* buffer_flush_thread()
148161

149162
static int32_t buffer_flush()
150163
{
151-
152164
this.cur_state = ON_FLUSHING;
153165

154-
int32_t ret = 0;
155166
pthread_t tid;
156167
pthread_attr_t attr;
157168

169+
int32_t ret = 0;
170+
158171
if (pthread_attr_init(&attr) != 0 ||
159172
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0 ||
160173
(ret = pthread_create(&tid, &attr, buffer_flush_thread, NULL)) != 0)
161174
{
162-
mc_logger->log(EXTENSION_LOG_WARNING, NULL,
163-
"Can't create buffer flush thread: %s\n", strerror(ret));
175+
perror("Can't create buffer flush thread");
176+
return ret;
164177
}
165178

166179
return ret;
@@ -171,6 +184,9 @@ static void buffer_add(const logtype* log)
171184

172185
struct cmd_in_second_buffer* buffer = &this.buffer;
173186

187+
buffer->ring[buffer->rear] = *log;
188+
buffer->rear = (buffer->rear+1) % buffer->capacity;
189+
174190
const bool buffer_full = (buffer->rear+1) % buffer->capacity == buffer->front;
175191

176192
if (buffer_full) {
@@ -181,41 +197,55 @@ static void buffer_add(const logtype* log)
181197
buffer->front = (buffer->front+1) % buffer->capacity;
182198
}
183199

184-
buffer->ring[buffer->rear] = *log;
185-
buffer->rear = (buffer->rear+1) % buffer->capacity;
200+
}
201+
202+
static void timer_add()
203+
{
204+
struct cmd_in_second_timer* timer = &this.timer;
205+
206+
const bool timer_full = (timer->rear+1) % timer->capacity == timer->front;
207+
208+
if (timer_full) {
209+
timer->front = (timer->front+1) % timer->capacity;
210+
}
211+
212+
if (gettimeofday(&timer->ring[timer->rear], NULL) == -1) {
213+
perror("gettimeofday failed");
214+
return;
215+
};
216+
217+
timer->rear = (timer->rear+1) % timer->capacity;
186218
}
187219

188220
static bool is_cmd_to_log(const char* collection_name, const char* cmd)
189221
{
190-
return strcmp(this.collection_name, collection_name) == 0 && strcmp(this.cmd, cmd) == 0;
222+
return strcmp(this.collection_name, collection_name) == 0 &&
223+
strcmp(this.cmd, cmd) == 0;
191224
}
192225

193-
bool cmd_in_second_write(const char* collection_name, const char* cmd, const char* key, const char* client_ip)
226+
bool cmd_in_second_write(const char* collection_name, const char* cmd,
227+
const char* key, const char* client_ip)
194228
{
195229
if (this.cur_state != ON_LOGGING || !is_cmd_to_log(collection_name, cmd)) {
196230
return false;
197231
}
198232

199-
timertype *timer = &this.timer;
200-
201-
logtype log = {"", "", 0};
233+
logtype log = {"", ""};
202234
snprintf(log.client_ip, IP_LENGTH, "%s", client_ip);
203235
snprintf(log.key, KEY_LENGTH, "%s", key);
204236

205-
if (timer->counter == 0) {
206-
timer->size++;
207-
gettimeofday(&timer->times[timer->size-1], NULL);
237+
if (this.timer.circular_counter == 0) {
238+
timer_add();
208239
}
209240

210-
log.timer_idx = timer->size-1;
211-
212241
buffer_add(&log);
213-
timer->counter = (timer->counter+1) % LOG_PER_TIMER;
242+
this.timer.circular_counter = (this.timer.circular_counter+1) % this.log_per_timer;
214243

215244
return true;
216245
}
217246

218-
int32_t cmd_in_second_start(const char* collection_name, const char* cmd, const int32_t bulk_limit)
247+
int32_t cmd_in_second_start(const char* collection_name, const char* cmd,
248+
const int32_t bulk_limit)
219249
{
220250

221251
if (this.cur_state != NOT_STARTED) {
@@ -233,17 +263,21 @@ int32_t cmd_in_second_start(const char* collection_name, const char* cmd, const
233263
return CMD_IN_SECOND_NO_MEM;
234264
}
235265

236-
this.timer.size = 0;
237-
this.timer.counter = 0;
238-
this.timer.times = (struct timeval*)malloc(bulk_limit * sizeof(struct timeval));
266+
this.log_per_timer = bulk_limit / 10 + (bulk_limit % 10 != 0);
267+
this.timer.capacity = this.log_per_timer + 1;
268+
this.timer.front = 0;
269+
this.timer.rear = 0;
270+
this.timer.circular_counter = 0;
271+
272+
this.timer.ring = (struct timeval*)malloc(this.timer.capacity * sizeof(struct timeval));
239273

240-
if (this.timer.times == NULL) {
274+
if (this.timer.ring == NULL) {
241275
free(this.buffer.ring);
242276
return CMD_IN_SECOND_NO_MEM;
243277
}
244278

245-
sprintf(this.collection_name, "%s", collection_name);
246-
sprintf(this.cmd, "%s", cmd);
279+
snprintf(this.collection_name, 5, "%s", collection_name);
280+
snprintf(this.cmd, 15, "%s", cmd);
247281

248282
this.cur_state = ON_LOGGING;
249283

include/memcached/types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ struct iovec {
3838
#define SUPPORT_BOP_SMGET
3939
#define JHPARK_OLD_SMGET_INTERFACE
4040
#define MAX_EFLAG_COMPARE_COUNT 100
41-
41+
#define CMD_IN_SECOND 1
4242

4343
#ifdef __cplusplus
4444
extern "C" {

0 commit comments

Comments
 (0)