Motr  M0
vec.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2011-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 #include "ut/ut.h"
24 #include "lib/vec.h"
25 #include "lib/memory.h"
26 #include "lib/misc.h"
27 #include "lib/assert.h"
28 #include "lib/bitmap.h"
29 #include "lib/time.h"
30 #include "lib/arith.h"
31 #include "lib/errno.h"
32 
33 static void test_ivec_cursor(void);
34 static void test_bufvec_cursor(void);
35 static void test_bufvec_cursor_copyto_copyfrom(void);
36 static void test_indexvec_varr_cursor(void);
37 static void test_cmp(void);
38 
39 enum {
40  NR = 255,
41  IT = 6,
42  NR2 = 127
43 };
44 
45 static m0_bcount_t segs[NR * IT];
46 
47 static struct m0_vec t = {
48  .v_nr = NR * IT,
49  .v_count = segs
50 };
51 
52 void test_vec(void)
53 {
54  int i;
55  int it;
57  m0_bcount_t sum0;
58  m0_bcount_t sum1;
59  m0_bcount_t step;
60  bool eov;
61  void **buf;
62 
63  struct m0_vec_cursor c;
64  struct m0_bufvec bv;
65 
67  M0_UT_ASSERT(buf != NULL);
68 
69  for (count = 0, it = 1, sum0 = i = 0; i < ARRAY_SIZE(segs); ++i) {
70  segs[i] = count * it;
71  sum0 += segs[i];
72  if (++count == NR) {
73  count = 0;
74  ++it;
75  }
76  };
77 
78  M0_UT_ASSERT(m0_vec_count(&t) == sum0);
79 
81  for (i = 0; i < sum0; ++i) {
82  eov = m0_vec_cursor_move(&c, 1);
83  M0_UT_ASSERT(eov == (i == sum0 - 1));
84  }
85 
87  count = 0;
88  it = 1;
89  sum1 = 0;
90  while (!m0_vec_cursor_move(&c, 0)) {
91  if (count * it != 0) {
92  step = m0_vec_cursor_step(&c);
93  sum1 += step;
94  M0_UT_ASSERT(step == count * it);
95  eov = m0_vec_cursor_move(&c, step);
96  M0_UT_ASSERT(eov == (sum1 == sum0));
97  }
98  if (++count == NR) {
99  count = 0;
100  ++it;
101  }
102  }
103  m0_vec_cursor_init(&c, &t);
104  m0_vec_cursor_move(&c, sum0);
106 
107  M0_UT_ASSERT(m0_bufvec_alloc(&bv, NR, M0_SEG_SIZE) == 0);
108  M0_UT_ASSERT(bv.ov_vec.v_nr == NR);
109  for (i = 0; i < NR; ++i) {
110  M0_UT_ASSERT(bv.ov_vec.v_count[i] == M0_SEG_SIZE);
111  M0_UT_ASSERT(bv.ov_buf[i] != NULL);
112  }
113  m0_bufvec_free(&bv);
114  M0_UT_ASSERT(bv.ov_vec.v_nr == 0);
115  M0_UT_ASSERT(bv.ov_buf == NULL);
116  m0_bufvec_free(&bv); /* no-op */
117  m0_fi_enable_once("bufvec_alloc", "buf-alloc-fail");
118  M0_UT_ASSERT(m0_bufvec_alloc(&bv, NR, M0_SEG_SIZE) == -ENOMEM);
119  m0_fi_enable_once("bufvec_alloc", "empty-fail");
120  M0_UT_ASSERT(m0_bufvec_empty_alloc(&bv, NR) == -ENOMEM);
121  M0_UT_ASSERT(m0_bufvec_alloc(&bv, NR2, M0_SEG_SIZE) == 0);
122  M0_UT_ASSERT(bv.ov_vec.v_nr == NR2);
123  for (i = 0; i < NR2; ++i)
124  buf[i] = bv.ov_buf[i];
125  M0_UT_ASSERT(m0_bufvec_extend(&bv, NR2) == 0);
126  M0_UT_ASSERT(bv.ov_vec.v_nr == 2 * NR2);
127  for (i = 0; i < 2 * NR2; ++i) {
128  M0_UT_ASSERT(bv.ov_vec.v_count[i] == M0_SEG_SIZE);
129  M0_UT_ASSERT(bv.ov_buf[i] != NULL);
130  }
131  for (i = 0; i < NR2; ++i)
132  M0_UT_ASSERT(bv.ov_buf[i] == buf[i]);
133 
134  m0_bufvec_free(&bv);
135 
136  M0_UT_ASSERT(m0_bufvec_alloc_aligned(&bv, NR, M0_SEG_SIZE,
137  M0_SEG_SHIFT) == 0);
138  M0_UT_ASSERT(bv.ov_vec.v_nr == NR);
139  for (i = 0; i < NR; ++i) {
140  M0_UT_ASSERT(bv.ov_vec.v_count[i] == M0_SEG_SIZE);
141  M0_UT_ASSERT(bv.ov_buf[i] != NULL);
142  M0_UT_ASSERT(m0_addr_is_aligned(bv.ov_buf[i], M0_SEG_SHIFT));
143  }
144  m0_bufvec_free_aligned(&bv, M0_SEG_SHIFT);
145  M0_UT_ASSERT(bv.ov_vec.v_nr == 0);
146  M0_UT_ASSERT(bv.ov_buf == NULL);
147  m0_bufvec_free_aligned(&bv, M0_SEG_SHIFT); /* no-op */
148 
153  test_cmp();
154 }
155 
156 static void test_indexvec_varr_cursor(void)
157 {
158  struct m0_indexvec_varr *ivv;
159  struct m0_ivec_varr_cursor ivc;
160  m0_bcount_t c;
161  int nr;
162  int rc;
163 
164  M0_ALLOC_PTR(ivv);
165  M0_UT_ASSERT(ivv != NULL);
166 
167  M0_SET0(ivv);
168  rc = m0_indexvec_varr_alloc(ivv, 4);
169  M0_UT_ASSERT(rc == 0);
170 
171  /* data initialization begins */
172  *(m0_bindex_t*)(m0_varr_ele_get(&ivv->iv_index, 0)) = 0;
173  *(m0_bindex_t*)(m0_varr_ele_get(&ivv->iv_index, 1)) = 1;
174  *(m0_bindex_t*)(m0_varr_ele_get(&ivv->iv_index, 2)) = 2;
175  *(m0_bindex_t*)(m0_varr_ele_get(&ivv->iv_index, 3)) = 8;
176  *(m0_bcount_t*)(m0_varr_ele_get(&ivv->iv_count, 0)) = 2;
177  *(m0_bcount_t*)(m0_varr_ele_get(&ivv->iv_count, 1)) = 3; /*overlapping*/
178  *(m0_bcount_t*)(m0_varr_ele_get(&ivv->iv_count, 2)) = 1; /*overlapping*/
179  *(m0_bcount_t*)(m0_varr_ele_get(&ivv->iv_count, 3)) = 4;
180  /* data initialization ends */
181 
182  m0_varr_for(&ivv->iv_count, uint64_t *, i, countp) {
183  /*printf("data[%d] = %d\n", (int)i, (int)*(uint64_t*)countp);*/
184  } m0_varr_endfor;
185  m0_varr_for(&ivv->iv_index, uint64_t *, i, indexp) {
186  /*printf("data[%d] = %d\n", (int)i, (int)*(uint64_t*)indexp);*/
187  } m0_varr_endfor;
188 
189  /* test move */
190  m0_ivec_varr_cursor_init(&ivc, ivv);
191  M0_UT_ASSERT(ivc.vc_ivv == ivv);
192  M0_UT_ASSERT(ivc.vc_seg == 0);
193  M0_UT_ASSERT(ivc.vc_offset == 0);
194 
197  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 0) == 0);
198  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 1) == 1);
199  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 2) == 2);
200  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 3) == 3);
201  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 4) == 4);
202  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 5) == 4);
203 
207 
209  M0_UT_ASSERT( m0_ivec_varr_cursor_index(&ivc) == 1); /* seg[1] */
211  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 1) == 1);
212  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 2) == 2);
213  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 3) == 3);
214  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 4) == 4);
215  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 5) == 4);
216 
220 
222  M0_UT_ASSERT( m0_ivec_varr_cursor_index(&ivc) == 2); /* seg[2] */
224  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 2) == 2);
225  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 3) == 3);
226  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 4) == 3);
227 
229  M0_UT_ASSERT( m0_ivec_varr_cursor_index(&ivc) == 8); /* seg[3] */
231  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 8) == 8);
232  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 9) == 9);
233  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 12) == 12);
234  M0_UT_ASSERT( m0_ivec_varr_cursor_conti(&ivc, 13) == 12);
235 
236  M0_UT_ASSERT( m0_ivec_varr_cursor_move (&ivc, 4) ); /* at the end*/
237 
238  /* test move_to */
239  m0_ivec_varr_cursor_init(&ivc, ivv);
243 
250  M0_UT_ASSERT( m0_ivec_varr_cursor_move_to(&ivc, 12)); /* at the end*/
251 
252  m0_ivec_varr_cursor_init(&ivc, ivv);
253  c = 0;
254  nr = 0;
255  while (!m0_ivec_varr_cursor_move(&ivc, c)) {
256  c = m0_ivec_varr_cursor_step(&ivc);
257  ++nr;
258  }
259  M0_UT_ASSERT(nr == 4);
260 
262  m0_free(ivv);
263 }
264 
265 static void test_ivec_cursor(void)
266 {
267  int nr;
268  m0_bindex_t indexes[4];
269  m0_bcount_t counts[4];
270  m0_bcount_t c;
271  struct m0_indexvec ivec;
272  struct m0_ivec_cursor cur;
273 
274  indexes[0] = 0, counts[0] = 2;
275  indexes[1] = 1, counts[1] = 3; /* overlapping segment */
276  indexes[2] = 2, counts[2] = 1; /* overlapping segment */
277  indexes[3] = 8, counts[3] = 4;
278 
279  ivec.iv_index = indexes;
280  ivec.iv_vec.v_nr = 4;
281  ivec.iv_vec.v_count = counts;
282 
283  m0_ivec_cursor_init(&cur, &ivec);
284  M0_UT_ASSERT(cur.ic_cur.vc_vec == &ivec.iv_vec);
285  M0_UT_ASSERT(cur.ic_cur.vc_seg == 0);
286  M0_UT_ASSERT(cur.ic_cur.vc_offset == 0);
287 
296 
300 
302  M0_UT_ASSERT(m0_ivec_cursor_index(&cur) == 1); /* seg[1] */
309 
313 
315  M0_UT_ASSERT(m0_ivec_cursor_index(&cur) == 2); /* seg[2] */
320 
322  M0_UT_ASSERT(m0_ivec_cursor_index(&cur) == 8); /* seg[3] */
329 
330  /* test move_to */
331  m0_ivec_cursor_init(&cur, &ivec);
335 
342  M0_UT_ASSERT(m0_ivec_cursor_move_to(&cur, 12)); /* at the end*/
343 
344  m0_ivec_cursor_init(&cur, &ivec);
345  c = 0;
346  nr = 0;
347  while (!m0_ivec_cursor_move(&cur, c)) {
349  ++nr;
350  }
351  M0_UT_ASSERT(nr == 4);
352 
353  M0_UT_ASSERT(m0_vec_count(&ivec.iv_vec) == 10);
354  M0_UT_ASSERT(m0_indexvec_pack(&ivec) == 2);
355  M0_UT_ASSERT(m0_vec_count(&ivec.iv_vec) == 8);
356  M0_UT_ASSERT(ivec.iv_vec.v_nr == 2);
357  M0_UT_ASSERT(ivec.iv_index[0] == 0);
358  M0_UT_ASSERT(ivec.iv_vec.v_count[0] == 4);
359  M0_UT_ASSERT(ivec.iv_index[1] == 8);
360  M0_UT_ASSERT(ivec.iv_vec.v_count[1] == 4);
361  M0_UT_ASSERT(m0_indexvec_pack(&ivec) == 0);
362  M0_UT_ASSERT(m0_vec_count(&ivec.iv_vec) == 8);
363 }
364 
365 static void test_bufvec_cursor(void)
366 {
367  /* Create buffers with different shapes but same total size.
368  Also create identical buffers for exact shape testing,
369  and a couple of larger buffers whose bounds won't be reached.
370  */
371  enum { NR_BUFS = 10 };
372  static struct {
373  uint32_t num_segs;
375  } shapes[NR_BUFS] = {
376  [0] = { 1, 48 },
377  [1] = { 1, 48 },
378  [2] = { 2, 24 },
379  [3] = { 2, 24 },
380  [4] = { 3, 16 },
381  [5] = { 3, 16 },
382  [6] = { 4, 12 },
383  [7] = { 4, 12 },
384  [8] = { 6, 8 },
385  [9] = { 6, 8 },
386  };
387  static const char *msg = "abcdefghijklmnopqrstuvwxyz0123456789"
388  "ABCDEFGHIJK";
389  size_t msglen = strlen(msg)+1;
390  struct m0_bufvec bufs[NR_BUFS];
391  struct m0_bufvec *b;
392  int i;
393 
394  M0_SET_ARR0(bufs);
395  for (i = 0; i < NR_BUFS; ++i) {
396  M0_UT_ASSERT(msglen == shapes[i].num_segs * shapes[i].seg_size);
398  shapes[i].num_segs,
399  shapes[i].seg_size) == 0);
400  }
401  b = &bufs[0];
402  M0_UT_ASSERT(b->ov_vec.v_nr == 1);
403  memcpy(b->ov_buf[0], msg, msglen);
404  M0_UT_ASSERT(memcmp(b->ov_buf[0], msg, msglen) == 0);
405  for (i = 1; i < NR_BUFS; ++i) {
406  struct m0_bufvec_cursor s_cur;
407  struct m0_bufvec_cursor d_cur;
408  int j;
409  const char *p = msg;
410 
411  m0_bufvec_cursor_init(&s_cur, &bufs[i-1]);
412  m0_bufvec_cursor_init(&d_cur, &bufs[i]);
413  M0_UT_ASSERT(m0_bufvec_cursor_copy(&d_cur, &s_cur, msglen)
414  == msglen);
415 
416  /* verify cursor positions */
419 
420  /* verify data */
421  for (j = 0; j < bufs[i].ov_vec.v_nr; ++j) {
422  int k;
423  char *q;
424  for (k = 0; k < bufs[i].ov_vec.v_count[j]; ++k) {
425  q = bufs[i].ov_buf[j] + k;
426  M0_UT_ASSERT(*p++ == *q);
427  }
428  }
429  }
430 
431  /* bounded copy - dest buffer smaller */
432  {
433  struct m0_bufvec buf;
434  m0_bcount_t seg_size = shapes[NR_BUFS-1].seg_size - 1;
435  uint32_t num_segs = shapes[NR_BUFS-1].num_segs - 1;
436  m0_bcount_t buflen = seg_size * num_segs;
437  struct m0_bufvec_cursor s_cur;
438  struct m0_bufvec_cursor d_cur;
439  int j;
440  const char *p = msg;
441  int len;
442 
443  M0_UT_ASSERT(m0_bufvec_alloc(&buf, num_segs, seg_size) == 0);
444  M0_UT_ASSERT(buflen < msglen);
445 
446  m0_bufvec_cursor_init(&s_cur, &bufs[NR_BUFS-1]);
447  m0_bufvec_cursor_init(&d_cur, &buf);
448 
449  M0_UT_ASSERT(m0_bufvec_cursor_copy(&d_cur, &s_cur, msglen)
450  == buflen);
451 
452  /* verify cursor positions */
455 
456  /* check partial copy correct */
457  len = 0;
458  for (j = 0; j < buf.ov_vec.v_nr; ++j) {
459  int k;
460  char *q;
461  for (k = 0; k < buf.ov_vec.v_count[j]; ++k) {
462  q = buf.ov_buf[j] + k;
463  M0_UT_ASSERT(*p++ == *q);
464  len++;
465  }
466  }
467  M0_UT_ASSERT(len == buflen);
469  }
470 
471  /* bounded copy - source buffer smaller */
472  {
473  struct m0_bufvec buf;
474  m0_bcount_t seg_size = shapes[NR_BUFS-1].seg_size + 1;
475  uint32_t num_segs = shapes[NR_BUFS-1].num_segs + 1;
476  m0_bcount_t buflen = seg_size * num_segs;
477  struct m0_bufvec_cursor s_cur;
478  struct m0_bufvec_cursor d_cur;
479  int j;
480  const char *p = msg;
481  int len;
482 
483  M0_UT_ASSERT(m0_bufvec_alloc(&buf, num_segs, seg_size) == 0);
484  M0_UT_ASSERT(buflen > msglen);
485 
486  m0_bufvec_cursor_init(&s_cur, &bufs[NR_BUFS-1]);
487  m0_bufvec_cursor_init(&d_cur, &buf);
488 
489  M0_UT_ASSERT(m0_bufvec_cursor_copy(&d_cur, &s_cur, buflen)
490  == msglen);
491 
492  /* verify cursor positions */
495 
496  /* check partial copy correct */
497  len = 0;
498  for (j = 0; j < buf.ov_vec.v_nr; ++j) {
499  int k;
500  char *q;
501  for (k = 0; k < buf.ov_vec.v_count[j] && len < msglen;
502  k++) {
503  q = buf.ov_buf[j] + k;
504  M0_UT_ASSERT(*p++ == *q);
505  len++;
506  }
507  }
509  }
510 
511  /* free buffer pool */
512  for (i = 0; i < ARRAY_SIZE(bufs); ++i)
513  m0_bufvec_free(&bufs[i]);
514 }
515 
517 {
518  struct struct_int {
519  uint32_t int1;
520  uint32_t int2;
521  uint32_t int3;
522  };
523 
524  struct struct_char {
525  char char1;
526  char char2;
527  char char3;
528  };
529 
530  static const struct struct_int struct_int1 = {
531  .int1 = 111,
532  .int2 = 112,
533  .int3 = 113
534  };
535 
536  static const struct struct_char struct_char1 = {
537  .char1 = 'L',
538  .char2 = 'M',
539  .char3 = 'N'
540  };
541 
542  void *area1;
543  struct m0_bufvec bv1;
544  struct m0_bufvec_cursor dcur1;
545  struct struct_int *struct_int2 = NULL;
546  struct struct_char *struct_char2 = NULL;
547  struct struct_int struct_int3;
548  struct struct_char struct_char3;
549  m0_bcount_t nbytes;
550  m0_bcount_t nbytes_copied;
551  uint32_t i;
552  int rc;
553 
554  /* Prepare for the destination buffer and the cursor. */
555  nbytes = sizeof struct_int1 * 4 + sizeof struct_char1 * 4 + 1;
556 
557  area1 = m0_alloc(nbytes);
558  M0_UT_ASSERT(area1 != NULL);
559 
560  bv1 = (struct m0_bufvec) M0_BUFVEC_INIT_BUF(&area1, &nbytes);
561  m0_bufvec_cursor_init(&dcur1, &bv1);
562 
563  M0_UT_ASSERT(m0_bufvec_cursor_step(&dcur1) == nbytes);
564 
565  /*
566  * Copy data to the destination cursor using the API
567  * m0_bufvec_cursor_copyto().
568  */
569  for (i = 0; i < 4; ++i) {
570  /* Copy struct_int1 to the bufvec. */
571  nbytes_copied = m0_bufvec_cursor_copyto(&dcur1,
572  (void *)&struct_int1,
573  sizeof struct_int1);
574  M0_UT_ASSERT(nbytes_copied == sizeof struct_int1);
575 
576  /* Copy struct_char1 to the bufvec. */
577  nbytes_copied = m0_bufvec_cursor_copyto(&dcur1,
578  (void *)&struct_char1,
579  sizeof struct_char1);
580  M0_UT_ASSERT(nbytes_copied == sizeof struct_char1);
581  }
582 
583  /* Rewind the cursor. */
584  m0_bufvec_cursor_init(&dcur1, &bv1);
585  M0_UT_ASSERT(m0_bufvec_cursor_step(&dcur1) == nbytes);
586 
587  /* Verify data from the destination cursor. */
588  for (i = 0; i < 3; ++i) {
589  /* Read data into struct_int2 and verify it. */
590  struct_int2 = m0_bufvec_cursor_addr(&dcur1);
591  M0_UT_ASSERT(struct_int2 != NULL);
592 
593  M0_UT_ASSERT(struct_int2->int1 == struct_int1.int1);
594  M0_UT_ASSERT(struct_int2->int2 == struct_int1.int2);
595  M0_UT_ASSERT(struct_int2->int3 == struct_int1.int3);
596 
597  rc = m0_bufvec_cursor_move(&dcur1, sizeof *struct_int2);
598  M0_UT_ASSERT(rc == 0);
599 
600  /* Read data into struct_char2 and verify it. */
601  struct_char2 = m0_bufvec_cursor_addr(&dcur1);
602  M0_UT_ASSERT(struct_char2 != NULL);
603 
604  M0_UT_ASSERT(struct_char2->char1 == struct_char1.char1);
605  M0_UT_ASSERT(struct_char2->char2 == struct_char1.char2);
606  M0_UT_ASSERT(struct_char2->char3 == struct_char1.char3);
607 
608  rc = m0_bufvec_cursor_move(&dcur1, sizeof *struct_char2);
609  M0_UT_ASSERT(rc == 0);
610  }
611 
612  /* Rewind the cursor. */
613  m0_bufvec_cursor_init(&dcur1, &bv1);
614  M0_UT_ASSERT(m0_bufvec_cursor_step(&dcur1) == nbytes);
615 
616  /*
617  * Copy data from the cursor using the API m0_bufvec_cursor_copyfrom().
618  */
619 
620  for (i = 0; i < 3; ++i) {
621  /* Copy data from dcur into the struct_int3 and verify it. */
622  nbytes_copied = m0_bufvec_cursor_copyfrom(&dcur1, &struct_int3,
623  sizeof struct_int3);
624  M0_UT_ASSERT(nbytes_copied == sizeof struct_int3);
625 
626  M0_UT_ASSERT(struct_int3.int2 == struct_int1.int2);
627  M0_UT_ASSERT(struct_int3.int2 == struct_int1.int2);
628  M0_UT_ASSERT(struct_int3.int3 == struct_int1.int3);
629 
630  /* Copy data from dcur into the struct_char3 and verify it. */
631  nbytes_copied = m0_bufvec_cursor_copyfrom(&dcur1, &struct_char3,
632  sizeof struct_char3);
633  M0_UT_ASSERT(nbytes_copied == sizeof struct_char3);
634 
635  M0_UT_ASSERT(struct_char3.char1 == struct_char1.char1);
636  M0_UT_ASSERT(struct_char3.char2 == struct_char1.char2);
637  M0_UT_ASSERT(struct_char3.char3 == struct_char1.char3);
638  }
639 }
640 
641 static struct m0_bufvec *split(const char *src, int n)
642 {
643  struct m0_bitmap map;
644  int result;
645  struct m0_bufvec *vec;
646  int i;
647  int len;
648  int pos;
649  int off;
650  int tot = strlen(src) + 1 + n - 1;
651  static uint64_t seed = 0;
652 
653  M0_UT_ASSERT(n > 0);
654  if (seed == 0)
655  seed = m0_time_now();
656  result = m0_bitmap_init(&map, tot + 1);
657  M0_UT_ASSERT(result == 0);
658  m0_bitmap_set(&map, tot, true);
659  for (i = 0; i < n - 1; ++i) {
660  int p;
661 
662  do {
663  p = m0_rnd(tot, &seed);
664  } while (m0_bitmap_get(&map, p));
665  m0_bitmap_set(&map, p, true);
666  }
667  M0_ALLOC_PTR(vec);
668  M0_UT_ASSERT(vec != NULL);
669  M0_ALLOC_ARR(vec->ov_vec.v_count, n);
670  M0_UT_ASSERT(vec->ov_vec.v_count != NULL);
671  M0_ALLOC_ARR(vec->ov_buf, n);
672  M0_UT_ASSERT(vec->ov_buf != NULL);
673  vec->ov_vec.v_nr = n;
674  for (i = 0, len = 0, pos = 0, off = 0; i <= tot; ++i, ++len) {
675  if (m0_bitmap_get(&map, i)) {
676  M0_ALLOC_ARR(vec->ov_buf[pos], len);
677  M0_UT_ASSERT(vec->ov_buf[pos] != NULL);
678  vec->ov_vec.v_count[pos] = len;
679  memcpy(vec->ov_buf[pos], src + off, len);
680  off += len;
681  pos++;
682  len = -1;
683  continue;
684  }
685  }
687  return vec;
688 }
689 
690 static const char abc[] = "vextcwmflyjabszingqurdkoph";
691 static const char aBc[] = "vextcwmflyjabszingQurdkoph";
692 
693 static void test_cmp(void)
694 {
695  int n;
696  int i;
697 
698  for (n = 1; n < 15; ++n) {
699  for (i = 0; i < 1000; ++i) {
700  struct m0_bufvec *v0 = split(abc, n);
701  struct m0_bufvec *v1 = split(abc, 2 * n);
702  struct m0_bufvec_cursor c0;
703  struct m0_bufvec_cursor c1;
704  m0_bcount_t nob;
705 
706  M0_UT_ASSERT(m0_vec_count(&v0->ov_vec) == sizeof abc);
707  M0_UT_ASSERT(m0_vec_count(&v1->ov_vec) == sizeof abc);
708  m0_bufvec_cursor_init(&c0, v0);
709  m0_bufvec_cursor_init(&c1, v1);
710  M0_UT_ASSERT(m0_bufvec_cursor_cmp(&c0, &c1) == 0);
711  m0_bufvec_cursor_init(&c0, v0);
712  m0_bufvec_cursor_init(&c1, v1);
713  M0_UT_ASSERT(m0_bufvec_cursor_cmp(&c1, &c0) == 0);
714  m0_bufvec_cursor_init(&c0, v0);
715  m0_bufvec_cursor_init(&c1, v1);
716  M0_UT_ASSERT(m0_bufvec_cursor_cmp(&c0, &c0) == 0);
717  m0_bufvec_cursor_init(&c0, v0);
718  m0_bufvec_cursor_init(&c1, v1);
719  M0_UT_ASSERT(m0_bufvec_cursor_cmp(&c1, &c1) == 0);
720  m0_bufvec_free(v1);
721  v1 = split(aBc, 2 * n);
722  m0_bufvec_cursor_init(&c0, v0);
723  m0_bufvec_cursor_init(&c1, v1);
724  M0_UT_ASSERT(m0_bufvec_cursor_cmp(&c0, &c1) > 0);
725  m0_bufvec_cursor_init(&c0, v0);
726  m0_bufvec_cursor_init(&c1, v1);
727  M0_UT_ASSERT(m0_bufvec_cursor_cmp(&c1, &c0) < 0);
728  m0_bufvec_cursor_init(&c0, v0);
729  m0_bufvec_cursor_init(&c1, v1);
730  M0_UT_ASSERT(m0_bufvec_cursor_prefix(&c1, &c0) == 18);
731  m0_bufvec_cursor_init(&c0, v0);
732  m0_bufvec_cursor_init(&c1, v1);
733  nob = m0_bufvec_cursor_copy(&c1, &c0, sizeof abc - 1);
734  M0_UT_ASSERT(nob == sizeof abc - 1);
735  M0_UT_ASSERT(m0_bufvec_cursor_cmp(&c0, &c1) == 0);
736  m0_bufvec_cursor_init(&c0, v0);
737  m0_bufvec_cursor_init(&c1, v1);
738  nob = m0_bufvec_cursor_copy(&c1, &c0, sizeof abc);
739  M0_UT_ASSERT(nob == sizeof abc);
740  M0_UT_ASSERT(m0_bufvec_cursor_cmp(&c0, &c1) == 0);
741  m0_bufvec_cursor_init(&c0, v0);
742  m0_bufvec_cursor_init(&c1, v1);
743  nob = m0_bufvec_cursor_copy(&c1, &c0, sizeof abc + 1);
744  M0_UT_ASSERT(nob == sizeof abc);
745  M0_UT_ASSERT(m0_bufvec_cursor_cmp(&c0, &c1) == 0);
746  m0_bufvec_free(v0);
747  m0_bufvec_free(v1);
748  }
749  }
750 }
751 
752 /*
753  * Local variables:
754  * c-indentation-style: "K&R"
755  * c-basic-offset: 8
756  * tab-width: 8
757  * fill-column: 80
758  * scroll-step: 1
759  * End:
760  */
static m0_bcount_t seg_size
Definition: net.c:118
m0_bcount_t vc_offset
Definition: vec.h:722
#define M0_BUFVEC_INIT_BUF(addr_ptr, count_ptr)
Definition: vec.h:165
M0_INTERNAL void m0_ivec_cursor_init(struct m0_ivec_cursor *cur, const struct m0_indexvec *ivec)
Definition: vec.c:707
static struct m0_addb2_philter p
Definition: consumer.c:40
static size_t nr
Definition: dump.c:1505
M0_INTERNAL bool m0_ivec_varr_cursor_move_to(struct m0_ivec_varr_cursor *cur, m0_bindex_t dest)
Definition: vec.c:1250
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
M0_INTERNAL int m0_bitmap_init(struct m0_bitmap *map, size_t nr)
Definition: bitmap.c:86
static struct m0_semaphore q
Definition: rwlock.c:55
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_bitmap_fini(struct m0_bitmap *map)
Definition: bitmap.c:97
map
Definition: processor.c:112
M0_INTERNAL m0_bcount_t m0_ivec_cursor_step(const struct m0_ivec_cursor *cur)
Definition: vec.c:726
static bool m0_addr_is_aligned(const void *addr, unsigned shift)
Definition: memory.h:107
static void test_cmp(void)
Definition: vec.c:693
static struct buffer * cur(struct m0_addb2_mach *mach, m0_bcount_t space)
Definition: addb2.c:791
M0_INTERNAL m0_bindex_t m0_ivec_cursor_conti(const struct m0_ivec_cursor *cur, m0_bindex_t dest)
Definition: vec.c:765
static struct m0_bufvec * split(const char *src, int n)
Definition: vec.c:641
static const char abc[]
Definition: vec.c:690
struct m0_vec ov_vec
Definition: vec.h:147
static m0_bcount_t segs[NR *IT]
Definition: vec.c:45
static void test_indexvec_varr_cursor(void)
Definition: vec.c:156
M0_INTERNAL m0_bindex_t m0_ivec_varr_cursor_conti(const struct m0_ivec_varr_cursor *cur, m0_bindex_t dest)
Definition: vec.c:1271
M0_INTERNAL m0_bcount_t m0_ivec_varr_cursor_step(const struct m0_ivec_varr_cursor *cur)
Definition: vec.c:1224
Definition: vec.h:49
static struct m0_be_emap_cursor it
Definition: extmap.c:46
#define m0_varr_endfor
Definition: varr.h:264
uint64_t m0_bindex_t
Definition: types.h:80
M0_INTERNAL void * m0_bufvec_cursor_addr(struct m0_bufvec_cursor *cur)
Definition: vec.c:597
uint64_t m0_bcount_t
Definition: types.h:77
uint32_t vc_seg
Definition: vec.h:720
static int void * buf
Definition: dir.c:1019
#define M0_SET0(obj)
Definition: misc.h:64
Definition: vec.c:42
void ** ov_buf
Definition: vec.h:149
M0_INTERNAL bool m0_ivec_cursor_move_to(struct m0_ivec_cursor *cur, m0_bindex_t dest)
Definition: vec.c:745
M0_INTERNAL int m0_bufvec_extend(struct m0_bufvec *bufvec, uint32_t num_segs)
Definition: vec.c:228
Definition: sock.c:887
static m0_bcount_t count
Definition: xcode.c:167
M0_INTERNAL int m0_bufvec_cursor_cmp(struct m0_bufvec_cursor *c0, struct m0_bufvec_cursor *c1)
Definition: vec.c:639
M0_INTERNAL int m0_bufvec_alloc_aligned(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size, unsigned shift)
Definition: vec.c:355
M0_INTERNAL int m0_bufvec_alloc(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size)
Definition: vec.c:220
struct m0_vec iv_vec
Definition: vec.h:139
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
Definition: vec.c:395
m0_bindex_t * iv_index
Definition: vec.h:141
M0_INTERNAL bool m0_bufvec_cursor_move(struct m0_bufvec_cursor *cur, m0_bcount_t count)
Definition: vec.c:574
int i
Definition: dir.c:1033
M0_INTERNAL int m0_indexvec_varr_alloc(struct m0_indexvec_varr *ivec, uint32_t len)
Definition: vec.c:1136
M0_INTERNAL m0_bcount_t m0_bufvec_cursor_copyfrom(struct m0_bufvec_cursor *scur, void *ddata, m0_bcount_t num_bytes)
Definition: vec.c:692
#define M0_SET_ARR0(arr)
Definition: misc.h:72
M0_INTERNAL uint64_t m0_rnd(uint64_t max, uint64_t *seed)
Definition: misc.c:115
M0_INTERNAL m0_bindex_t m0_ivec_varr_cursor_index(const struct m0_ivec_varr_cursor *cur)
Definition: vec.c:1237
static void test_bufvec_cursor(void)
Definition: vec.c:365
M0_INTERNAL m0_bcount_t m0_bufvec_cursor_copy(struct m0_bufvec_cursor *dcur, struct m0_bufvec_cursor *scur, m0_bcount_t num_bytes)
Definition: vec.c:620
M0_INTERNAL void m0_vec_cursor_init(struct m0_vec_cursor *cur, const struct m0_vec *vec)
Definition: vec.c:92
M0_INTERNAL m0_bcount_t m0_bufvec_cursor_step(const struct m0_bufvec_cursor *cur)
Definition: vec.c:581
static void * vec
Definition: xcode.c:168
m0_time_t m0_time_now(void)
Definition: time.c:134
static struct m0_addb2_callback c
Definition: consumer.c:41
static void test_bufvec_cursor_copyto_copyfrom(void)
Definition: vec.c:516
M0_INTERNAL void m0_bufvec_cursor_init(struct m0_bufvec_cursor *cur, const struct m0_bufvec *bvec)
Definition: vec.c:563
Definition: vec.c:40
Definition: vec.c:41
void * m0_alloc(size_t size)
Definition: memory.c:126
struct m0_varr iv_index
Definition: vec.h:711
m0_bcount_t counts[SEGS_NR]
Definition: di.c:44
M0_INTERNAL void m0_bitmap_set(struct m0_bitmap *map, size_t idx, bool val)
Definition: bitmap.c:139
struct m0_varr iv_count
Definition: vec.h:708
uint32_t v_nr
Definition: vec.h:51
static struct m0_vec t
Definition: vec.c:47
m0_bcount_t * v_count
Definition: vec.h:53
M0_INTERNAL bool m0_ivec_cursor_move(struct m0_ivec_cursor *cur, m0_bcount_t count)
Definition: vec.c:718
M0_INTERNAL void m0_indexvec_varr_free(struct m0_indexvec_varr *ivec)
Definition: vec.c:1160
M0_INTERNAL void m0_bufvec_free_aligned(struct m0_bufvec *bufvec, unsigned shift)
Definition: vec.c:436
M0_INTERNAL m0_bcount_t m0_vec_count(const struct m0_vec *vec)
Definition: vec.c:53
M0_INTERNAL uint32_t m0_indexvec_pack(struct m0_indexvec *iv)
Definition: vec.c:521
M0_INTERNAL void m0_ivec_varr_cursor_init(struct m0_ivec_varr_cursor *cur, struct m0_indexvec_varr *ivec)
Definition: vec.c:1183
uint64_t n
Definition: fops.h:107
M0_INTERNAL m0_bcount_t m0_vec_cursor_step(const struct m0_vec_cursor *cur)
Definition: vec.c:125
M0_INTERNAL m0_bcount_t m0_bufvec_cursor_prefix(struct m0_bufvec_cursor *c0, struct m0_bufvec_cursor *c1)
Definition: vec.c:654
void test_vec(void)
Definition: vec.c:52
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL bool m0_vec_cursor_move(struct m0_vec_cursor *cur, m0_bcount_t count)
Definition: vec.c:102
M0_INTERNAL m0_bcount_t m0_bufvec_cursor_copyto(struct m0_bufvec_cursor *dcur, void *sdata, m0_bcount_t num_bytes)
Definition: vec.c:677
M0_INTERNAL bool m0_bitmap_get(const struct m0_bitmap *map, size_t idx)
Definition: bitmap.c:105
M0_INTERNAL m0_bindex_t m0_ivec_cursor_index(const struct m0_ivec_cursor *cur)
Definition: vec.c:733
static void test_ivec_cursor(void)
Definition: vec.c:265
static void m0_fi_enable_once(const char *func, const char *tag)
Definition: finject.h:301
#define m0_varr_for(arr, type, idx, obj)
Definition: varr.h:259
void m0_free(void *data)
Definition: memory.c:146
struct m0_pdclust_src_addr src
Definition: fd.c:108
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
static const char aBc[]
Definition: vec.c:691
#define M0_UT_ASSERT(a)
Definition: ut.h:46
M0_INTERNAL bool m0_ivec_varr_cursor_move(struct m0_ivec_varr_cursor *cur, m0_bcount_t count)
Definition: vec.c:1198
Definition: vec.h:145
M0_INTERNAL int m0_bufvec_empty_alloc(struct m0_bufvec *bufvec, uint32_t num_segs)
Definition: vec.c:213
M0_INTERNAL void * m0_varr_ele_get(struct m0_varr *arr, uint64_t index)
Definition: varr.c:505
struct m0_indexvec_varr * vc_ivv
Definition: vec.h:718