fix MinGW
[m6w6/libmemcached] / src / libmemcached / virtual_bucket.c
1 /*
2 +--------------------------------------------------------------------+
3 | libmemcached - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020 Michael Wallner <mike@php.net> |
13 +--------------------------------------------------------------------+
14 */
15
16 #include "libmemcached/common.h"
17
18 struct bucket_t {
19 uint32_t master;
20 uint32_t forward;
21 };
22
23 struct memcached_virtual_bucket_t {
24 bool has_forward;
25 uint32_t size;
26 uint32_t replicas;
27 struct bucket_t buckets[];
28 };
29
30 memcached_return_t memcached_virtual_bucket_create(memcached_st *self, const uint32_t *host_map,
31 const uint32_t *forward_map,
32 const uint32_t buckets,
33 const uint32_t replicas) {
34 if (self == NULL || host_map == NULL || buckets == 0U) {
35 return MEMCACHED_INVALID_ARGUMENTS;
36 }
37
38 memcached_virtual_bucket_free(self);
39
40 struct memcached_virtual_bucket_t *virtual_bucket = (struct memcached_virtual_bucket_t *) malloc(
41 sizeof(struct memcached_virtual_bucket_t) + sizeof(struct bucket_t) * buckets);
42
43 if (virtual_bucket == NULL) {
44 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
45 }
46
47 virtual_bucket->size = buckets;
48 virtual_bucket->replicas = replicas;
49 self->virtual_bucket = virtual_bucket;
50
51 uint32_t x = 0;
52 for (; x < buckets; x++) {
53 virtual_bucket->buckets[x].master = host_map[x];
54 if (forward_map) {
55 virtual_bucket->buckets[x].forward = forward_map[x];
56 } else {
57 virtual_bucket->buckets[x].forward = 0;
58 }
59 }
60
61 return MEMCACHED_SUCCESS;
62 }
63
64 void memcached_virtual_bucket_free(memcached_st *self) {
65 if (self) {
66 if (self->virtual_bucket) {
67 free(self->virtual_bucket);
68 self->virtual_bucket = NULL;
69 }
70 }
71 }
72
73 uint32_t memcached_virtual_bucket_get(const memcached_st *self, uint32_t digest) {
74 if (self) {
75 if (self->virtual_bucket) {
76 uint32_t result = (uint32_t)(digest & (self->virtual_bucket->size - 1));
77 return self->virtual_bucket->buckets[result].master;
78 }
79
80 return (uint32_t)(digest & (self->number_of_hosts - 1));
81 }
82
83 return 0;
84 }