libserverframe/src/idempotency/server/request_htable.c

160 lines
3.9 KiB
C

#include <limits.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include "fastcommon/shared_func.h"
#include "fastcommon/logger.h"
#include "fastcommon/fast_mblock.h"
#include "fastcommon/sched_thread.h"
#include "sf/sf_global.h"
#include "request_htable.h"
typedef struct idempotency_request_context {
uint32_t htable_capacity;
} IdempotencyRequestContext;
static IdempotencyRequestContext request_ctx;
void idempotency_request_init(const uint32_t htable_capacity)
{
request_ctx.htable_capacity = htable_capacity;
}
int idempotency_request_htable_add(IdempotencyRequestHTable *htable,
IdempotencyRequest *request)
{
int result;
IdempotencyRequest **bucket;
IdempotencyRequest *previous;
IdempotencyRequest *current;
bucket = htable->buckets + request->req_id % request_ctx.htable_capacity;
previous = NULL;
result = 0;
PTHREAD_MUTEX_LOCK(&htable->lock);
current = *bucket;
while (current != NULL) {
if (current->req_id == request->req_id) {
request->output = current->output;
request->finished = current->finished;
result = EEXIST;
break;
} else if (current->req_id > request->req_id) {
break;
}
previous = current;
current = current->next;
}
if (result == 0) {
if (previous == NULL) {
request->next = *bucket;
*bucket = request;
} else {
request->next = previous->next;
previous->next = request;
}
htable->count++;
}
PTHREAD_MUTEX_UNLOCK(&htable->lock);
if (result == 0) {
__sync_add_and_fetch(&request->ref_count, 2);
}
return result;
}
int idempotency_request_htable_remove(IdempotencyRequestHTable *htable,
const uint64_t req_id)
{
IdempotencyRequest **bucket;
IdempotencyRequest *previous;
IdempotencyRequest *current;
bucket = htable->buckets + req_id % request_ctx.htable_capacity;
previous = NULL;
PTHREAD_MUTEX_LOCK(&htable->lock);
current = *bucket;
while (current != NULL) {
if (current->req_id == req_id) {
if (previous == NULL) {
*bucket = current->next;
} else {
previous->next = current->next;
}
htable->count--;
break;
} else if (current->req_id > req_id) {
current = NULL;
break;
}
previous = current;
current = current->next;
}
PTHREAD_MUTEX_UNLOCK(&htable->lock);
if (current != NULL) {
idempotency_request_release(current);
return 0;
} else {
return ENOENT;
}
}
void idempotency_request_htable_clear(IdempotencyRequestHTable *htable)
{
IdempotencyRequest **bucket;
IdempotencyRequest **end;
IdempotencyRequest *head;
IdempotencyRequest *previous;
IdempotencyRequest *current;
IdempotencyRequest *deleted;
head = NULL;
PTHREAD_MUTEX_LOCK(&htable->lock);
do {
if (htable->count == 0) {
break;
}
previous = NULL;
end = htable->buckets + request_ctx.htable_capacity;
for (bucket=htable->buckets; bucket<end; bucket++) {
if (*bucket == NULL) {
continue;
}
current = *bucket;
do {
if (previous == NULL) {
head = current;
} else {
previous->next = current;
}
previous = current;
current = current->next;
} while (current != NULL);
*bucket = NULL;
}
if (previous != NULL) {
previous->next = NULL;
}
htable->count = 0;
} while (0);
PTHREAD_MUTEX_UNLOCK(&htable->lock);
while (head != NULL) {
deleted = head;
head = head->next;
idempotency_request_release(deleted);
}
}