Motr  M0
misc.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26 
27 #include "lib/types.h" /* m0_uint128 */
28 #include "lib/string.h" /* m0_startswith */
29 #include "lib/time.h" /* m0_time_ t */
30 #include "lib/memory.h" /* M0_ALLOC_ARR */
31 #include "lib/arith.h" /* m0_rnd */
32 #include "ut/ut.h" /* M0_UT_ASSERT */
33 
34 #define BM_COMMON_STR "bm-majority-algorithm"
35 
36 enum {
39 };
40 
41 static const struct m0_uint128 zero = M0_UINT128(0, 0);
42 static const struct m0_uint128 one = M0_UINT128(0, 1);
43 static const struct m0_uint128 two = M0_UINT128(0, 2);
44 static const struct m0_uint128 three = M0_UINT128(0, 3);
45 static const struct m0_uint128 cmax64 = M0_UINT128(0, UINT64_MAX);
46 static const struct m0_uint128 cmax64_1 = M0_UINT128(1, 0);
47 static const struct m0_uint128 cmax64_2 = M0_UINT128(1, 1);
49 
50 static void uint128_add_check(const struct m0_uint128 *a,
51  const struct m0_uint128 *b,
52  const struct m0_uint128 *sum)
53 {
54  struct m0_uint128 result;
55 
56  m0_uint128_add(&result, a, b);
57  M0_UT_ASSERT(m0_uint128_eq(&result, sum));
58 
59  m0_uint128_add(&result, b, a);
60  M0_UT_ASSERT(m0_uint128_eq(&result, sum));
61 }
62 
63 static void uint128_add_ut(void)
64 {
77 }
78 
79 /* a * b = c */
80 static void uint128_mul_check(uint64_t a,
81  uint64_t b,
82  const struct m0_uint128 *c)
83 {
84  struct m0_uint128 result;
85 
86  m0_uint128_mul64(&result, a, b);
87  M0_UT_ASSERT(m0_uint128_eq(&result, c));
88 }
89 
90 static void uint128_mul_check1(uint64_t a,
91  uint64_t b,
92  const struct m0_uint128 *c)
93 {
94  uint128_mul_check(a, b, c);
95  uint128_mul_check(b, a, c);
96 }
97 
98 static void uint128_mul_ut(void)
99 {
100  uint128_mul_check1(0, 0, &zero);
101  uint128_mul_check1(0, 1, &zero);
103  uint128_mul_check1(1, 1, &one);
104  uint128_mul_check1(1, 2, &two);
109  &M0_UINT128(UINT64_MAX - 1, 1));
113  (uint64_t) UINT32_MAX << 32));
115 }
116 
117 static void test_forall_exists(void)
118 {
119  const char s[] = "0123456789";
120 
121  M0_UT_ASSERT(m0_forall(i, sizeof s, s[i] != 'a'));
122  M0_UT_ASSERT(m0_exists(i, sizeof s, s[i] == '0'));
123  M0_UT_ASSERT(m0_exists(i, sizeof s, s[i] == '5'));
124  M0_UT_ASSERT(m0_exists(i, sizeof s, s[i] == '9'));
125  M0_UT_ASSERT(!m0_exists(i, sizeof s, s[i] == 'a'));
126 }
127 
128 static void test_str_startswith(void)
129 {
130  const char s[] = "foobar";
131 
132  M0_UT_ASSERT(m0_startswith("foo", s));
134  M0_UT_ASSERT(!m0_startswith("bar", s));
135  M0_UT_ASSERT(!m0_startswith("foobarbaz", s));
137  M0_UT_ASSERT(m0_startswith("", ""));
138 }
139 
140 static void test_majority_ident_arr(void)
141 {
142  struct m0_key_val *kv_arr;
143  struct m0_key_val *mjr;
144  uint32_t *key_arr;
145  struct m0_buf *val_arr;
146  m0_time_t seed;
147  uint32_t i;
148  uint32_t vote_nr;
149 
151  M0_UT_ASSERT(kv_arr != NULL);
153  M0_UT_ASSERT(val_arr != NULL);
155  M0_UT_ASSERT(key_arr != NULL);
156 
157  for (i = 0; i < BM_MJR_ODD_ARR_LEN; ++i) {
158  m0_buf_init(&val_arr[i], BM_COMMON_STR, strlen(BM_COMMON_STR));
159  }
160  for (i = 0; i < BM_MJR_ODD_ARR_LEN; ++i) {
161  key_arr[i] = i;
162  }
163  for (i = 0; i < BM_MJR_ODD_ARR_LEN; ++i) {
164  m0_key_val_init(&kv_arr[i], &M0_BUF_INIT_PTR(&key_arr[i]),
165  &val_arr[i]);
166  }
167  vote_nr = 0;
169  &vote_nr);
170  M0_UT_ASSERT(mjr != NULL);
171  M0_UT_ASSERT(vote_nr == BM_MJR_ODD_ARR_LEN);
172 
173  /* Since all values are identical, pick a random one to compare. */
174  seed = m0_time_now();
176  M0_UT_ASSERT(m0_buf_eq(&kv_arr[i].kv_val, &mjr->kv_val));
177  m0_free(key_arr);
178  m0_free(val_arr);
179  m0_free(kv_arr);
180 }
181 
182 static void test_majority_dist_val(void)
183 {
184  struct m0_key_val *kv_arr;
185  struct m0_key_val *mjr;
186  uint32_t *key_arr;
187  uint32_t *val_arr;
188  uint32_t i;
189  uint32_t vote_nr;
190 
192  M0_UT_ASSERT(kv_arr != NULL);
194  M0_UT_ASSERT(val_arr != NULL);
196  M0_UT_ASSERT(key_arr != NULL);
197 
198  for (i = 0; i < BM_MJR_ODD_ARR_LEN; ++i) {
199  val_arr[i] = i;
200  }
201  for (i = 0; i < BM_MJR_ODD_ARR_LEN; ++i) {
202  key_arr[i] = i;
203  }
204  for (i = 0; i < BM_MJR_ODD_ARR_LEN; ++i) {
205  m0_key_val_init(&kv_arr[i], &M0_BUF_INIT_PTR(&key_arr[i]),
206  &M0_BUF_INIT_PTR(&val_arr[i]));
207  }
208  vote_nr = 0;
210  &vote_nr);
211  M0_UT_ASSERT(mjr == NULL);
212  M0_UT_ASSERT(vote_nr == 1);
213 
214  m0_free(key_arr);
215  m0_free(val_arr);
216  m0_free(kv_arr);
217 }
218 
219 static void test_majority_tie(void)
220 {
221  struct m0_key_val *kv_arr;
222  struct m0_key_val *mjr;
223  uint32_t *key_arr;
224  uint32_t *val_arr;
225  uint32_t i;
226  uint32_t vote_nr;
227 
229  M0_UT_ASSERT(kv_arr != NULL);
231  M0_UT_ASSERT(val_arr != NULL);
233  M0_UT_ASSERT(key_arr != NULL);
234 
235  for (i = 0; i < BM_MJR_EVEN_ARR_LEN; ++i) {
236  val_arr[i] = i % 2;
237  }
238  for (i = 0; i < BM_MJR_EVEN_ARR_LEN; ++i) {
239  key_arr[i] = i;
240  }
241  for (i = 0; i < BM_MJR_EVEN_ARR_LEN; ++i) {
242  m0_key_val_init(&kv_arr[i], &M0_BUF_INIT_PTR(&key_arr[i]),
243  &M0_BUF_INIT_PTR(&val_arr[i]));
244  }
245  vote_nr = 0;
247  &vote_nr);
248  M0_UT_ASSERT(mjr == NULL);
249  M0_UT_ASSERT(vote_nr == BM_MJR_EVEN_ARR_LEN / 2);
250 
251  m0_free(key_arr);
252  m0_free(val_arr);
253  m0_free(kv_arr);
254 }
255 
256 static void test_majority_get(void)
257 {
261 }
262 
263 void m0_test_misc(void)
264 {
265  uint128_add_ut();
266  uint128_mul_ut();
270 }
271 
272 /*
273  * Local variables:
274  * c-indentation-style: "K&R"
275  * c-basic-offset: 8
276  * tab-width: 8
277  * fill-column: 79
278  * scroll-step: 1
279  * End:
280  */
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
#define NULL
Definition: misc.h:38
#define BM_COMMON_STR
Definition: misc.c:34
static void uint128_mul_ut(void)
Definition: misc.c:98
static void test_forall_exists(void)
Definition: misc.c:117
M0_INTERNAL bool m0_buf_eq(const struct m0_buf *x, const struct m0_buf *y)
Definition: buf.c:90
M0_INTERNAL bool m0_uint128_eq(const struct m0_uint128 *u0, const struct m0_uint128 *u1)
Definition: misc.c:39
uint64_t m0_time_t
Definition: time.h:37
static const struct m0_uint128 cmax64
Definition: misc.c:45
static const struct m0_uint128 three
Definition: misc.c:44
M0_INTERNAL void m0_buf_init(struct m0_buf *buf, void *data, uint32_t nob)
Definition: buf.c:37
static int sum
Definition: rwlock.c:53
#define m0_exists(var, nr,...)
Definition: misc.h:134
static const struct m0_uint128 cmax128
Definition: misc.c:48
M0_INTERNAL bool m0_startswith(const char *prefix, const char *str)
Definition: string.c:98
static void uint128_add_ut(void)
Definition: misc.c:63
#define UINT32_MAX
Definition: types.h:41
static void test_str_startswith(void)
Definition: misc.c:128
static const struct m0_uint128 zero
Definition: misc.c:41
Definition: buf.h:37
int i
Definition: dir.c:1033
static void uint128_mul_check(uint64_t a, uint64_t b, const struct m0_uint128 *c)
Definition: misc.c:80
uint64_t m0_rnd(uint64_t max, uint64_t *prev)
Definition: misc.c:115
static void uint128_add_check(const struct m0_uint128 *a, const struct m0_uint128 *b, const struct m0_uint128 *sum)
Definition: misc.c:50
static void test_majority_tie(void)
Definition: misc.c:219
m0_time_t m0_time_now(void)
Definition: time.c:134
static struct m0_addb2_callback c
Definition: consumer.c:41
M0_INTERNAL void m0_key_val_init(struct m0_key_val *kv, const struct m0_buf *key, const struct m0_buf *val)
Definition: misc.c:369
static const struct m0_uint128 cmax64_2
Definition: misc.c:47
#define UINT64_MAX
Definition: types.h:44
void m0_test_misc(void)
Definition: misc.c:263
static void uint128_mul_check1(uint64_t a, uint64_t b, const struct m0_uint128 *c)
Definition: misc.c:90
static void test_majority_get(void)
Definition: misc.c:256
#define m0_forall(var, nr,...)
Definition: misc.h:112
static const struct m0_uint128 cmax64_1
Definition: misc.c:46
static const struct m0_uint128 two
Definition: misc.c:43
#define M0_BUF_INIT_PTR(p)
Definition: buf.h:69
struct m0_buf kv_val
Definition: misc.h:419
M0_INTERNAL void m0_uint128_mul64(struct m0_uint128 *res, uint64_t a, uint64_t b)
Definition: misc.c:76
static void test_majority_dist_val(void)
Definition: misc.c:182
#define M0_UINT128(hi, lo)
Definition: types.h:40
static void test_majority_ident_arr(void)
Definition: misc.c:140
M0_INTERNAL void * m0_vote_majority_get(struct m0_key_val *arr, uint32_t len, bool(*cmp)(const struct m0_buf *, const struct m0_buf *), uint32_t *vote_nr)
Definition: misc.c:383
void m0_free(void *data)
Definition: memory.c:146
static struct m0_addb2_source * s
Definition: consumer.c:39
#define M0_UT_ASSERT(a)
Definition: ut.h:46
M0_INTERNAL void m0_uint128_add(struct m0_uint128 *res, const struct m0_uint128 *a, const struct m0_uint128 *b)
Definition: misc.c:62
static const struct m0_uint128 one
Definition: misc.c:42