consolidate
[m6w6/libmemcached] / src / libmemcached / virtual_bucket.cc
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 #include "libmemcached/virtual_bucket.h"
18
19 struct bucket_t {
20 uint32_t master;
21 uint32_t forward;
22 };
23
24 struct memcached_virtual_bucket_t {
25 bool has_forward;
26 uint32_t size;
27 uint32_t replicas;
28 struct bucket_t buckets[];
29 };
30
31 memcached_return_t memcached_virtual_bucket_create(memcached_st *self, const uint32_t *host_map,
32 const uint32_t *forward_map,
33 const uint32_t buckets,
34 const uint32_t replicas) {
35 if (self == NULL || host_map == NULL || buckets == 0U) {
36 return MEMCACHED_INVALID_ARGUMENTS;
37 }
38
39 memcached_virtual_bucket_free(self);
40
41 struct memcached_virtual_bucket_t *virtual_bucket = (struct memcached_virtual_bucket_t *) malloc(
42 sizeof(struct memcached_virtual_bucket_t) + sizeof(struct bucket_t) * buckets);
43
44 if (virtual_bucket == NULL) {
45 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
46 }
47
48 virtual_bucket->size = buckets;
49 virtual_bucket->replicas = replicas;
50 self->virtual_bucket = virtual_bucket;
51
52 uint32_t x = 0;
53 for (; x < buckets; x++) {
54 virtual_bucket->buckets[x].master = host_map[x];
55 if (forward_map) {
56 virtual_bucket->buckets[x].forward = forward_map[x];
57 } else {
58 virtual_bucket->buckets[x].forward = 0;
59 }
60 }
61
62 return MEMCACHED_SUCCESS;
63 }
64
65 void memcached_virtual_bucket_free(memcached_st *self) {
66 if (self) {
67 if (self->virtual_bucket) {
68 free(self->virtual_bucket);
69 self->virtual_bucket = NULL;
70 }
71 }
72 }
73
74 uint32_t memcached_virtual_bucket_get(const memcached_st *self, uint32_t digest) {
75 if (self) {
76 if (self->virtual_bucket) {
77 uint32_t result = (uint32_t)(digest & (self->virtual_bucket->size - 1));
78 return self->virtual_bucket->buckets[result].master;
79 }
80
81 return (uint32_t)(digest & (self->number_of_hosts - 1));
82 }
83
84 return 0;
85 }