Motr  M0
idx.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 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 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CLIENT
24 #include "lib/trace.h"
25 
26 #include "motr/client.h"
27 #include "motr/st/st.h"
28 #include "motr/st/st_misc.h"
29 #include "motr/st/st_assert.h"
30 
31 #include "lib/memory.h"
32 
33 #define ST_VAL_STRING ("Client Index Test.")
34 
35 enum {
41 };
42 
45 static bool *deleted_kv_pairs;
46 
47 static int get_max_nr_kv_pairs(int idx_door_no)
48 {
49  int type;
50 
51  type = idx_door_no % 3;
52  if (type == 0)
53  return ST_SMALL_KV_PAIR_NUM;
54 
55  if (type == 1)
56  return ST_MEDIUM_KV_PAIR_NUM;
57 
58  if (type == 2)
59  return ST_LARGE_KV_PAIR_NUM;
60 
61  return -EINVAL;
62 }
63 
64 static void idx_bufvec_free(struct m0_bufvec *bv)
65 {
66  uint32_t i;
67  if (bv == NULL)
68  return;
69 
70  if (bv->ov_buf != NULL) {
71  for (i = 0; i < bv->ov_vec.v_nr; ++i)
72  if (bv->ov_buf[i] != NULL)
73  mem_free(bv->ov_buf[i]);
74  mem_free(bv->ov_buf);
75  }
76  mem_free(bv->ov_vec.v_count);
77  mem_free(bv);
78 }
79 
80 static struct m0_bufvec* idx_bufvec_alloc(int nr)
81 {
82  struct m0_bufvec *bv;
83 
84  bv = m0_alloc(sizeof *bv);
85  if (bv == NULL)
86  return NULL;
87 
88  bv->ov_vec.v_nr = nr;
90  if (bv->ov_vec.v_count == NULL)
91  goto FAIL;
92 
93  M0_ALLOC_ARR(bv->ov_buf, nr);
94  if (bv->ov_buf == NULL)
95  goto FAIL;
96 
97  return bv;
98 
99 FAIL:
100  m0_bufvec_free(bv);
101  return NULL;
102 }
103 
104 static bool is_kv_pair_deleted(int idx_door_no, int key_no)
105 {
106  int loc;
107 
108  loc = idx_door_no * ST_LARGE_KV_PAIR_NUM + key_no;
109  return deleted_kv_pairs[loc];
110 }
111 
112 static int idx_pick_keys(int idx_door_no,
113  struct m0_bufvec *keys, int *key_no_arr)
114 {
115  int i;
116  int rc;
117  int nr_kvp;
118  int nr_picked = 0;
119  int max_nr_kvp;
120  int key_no;
121  int klen;
122  char *prefix = NULL;
123  char *tmp_str = NULL;
124  char *key_str = NULL;
125  struct m0_uint128 id;
126 
127  if (keys == NULL)
128  return -EINVAL;
129 
130  rc = -ENOMEM;
132  if (prefix == NULL)
133  goto ERROR;
134 
135  tmp_str = m0_alloc(ST_MAX_KEY_LEN);
136  if (tmp_str == NULL)
137  goto ERROR;
138 
139  /*
140  * Keys are flled with this format (index fid:key's serial number).
141  */
142  id = test_index_ids[idx_door_no];
143  nr_kvp = keys->ov_vec.v_nr;
144  max_nr_kvp = get_max_nr_kv_pairs(idx_door_no);
145  if (nr_kvp > max_nr_kvp)
146  goto ERROR;
147 
148  for (i = 0; i < nr_kvp; i++) {
149  key_no = generate_random(max_nr_kvp);
150  if (is_kv_pair_deleted(idx_door_no, key_no))
151  continue;
152  sprintf(tmp_str,
153  "%" PRIx64 ":%" PRIx64 ":%d",
154  id.u_hi, id.u_lo, key_no);
155 
156  klen = strlen(tmp_str);
157  key_str = m0_alloc(klen + 1);
158  if (key_str == NULL)
159  goto ERROR;
160 
161  memcpy(key_str, tmp_str, klen);
162  key_str[klen] = '\0';
163  /* Set bufvec's of keys and vals*/
164  keys->ov_vec.v_count[i] = klen;
165  keys->ov_buf[i] = key_str;
166 
167  nr_picked++;
168  if (key_no_arr)
169  key_no_arr[i] = key_no;
170  }
171 
172  return nr_picked;
173 
174 ERROR:
175  if (prefix) m0_free(prefix);
176  if (tmp_str) m0_free(tmp_str);
177  if (key_str) m0_free(key_str);
178 
179  for (i = 0; i < keys->ov_vec.v_nr; ++i) {
180  if (keys->ov_buf[i])
181  mem_free(keys->ov_buf[i]);
182  keys->ov_buf[i] = NULL;
183  keys->ov_vec.v_count[i] = 0;
184  }
185 
186  return rc;
187 }
188 
189 static int idx_fill_kv_pairs(struct m0_uint128 id, int start,
190  struct m0_bufvec *keys,
191  struct m0_bufvec *vals)
192 {
193  int i;
194  int rc;
195  int nr_kvp;
196  int klen;
197  int vlen;
198  char *prefix = NULL;
199  char *tmp_str = NULL;
200  char *key_str = NULL;
201  char *val_str = NULL;
202 
203  rc = -ENOMEM;
205  if (prefix == NULL)
206  goto ERROR;
207 
208  tmp_str = m0_alloc(ST_MAX_KEY_LEN);
209  if (tmp_str == NULL)
210  goto ERROR;
211 
212  /*
213  * Keys are flled with this format (index fid:key's serial number).
214  * Values are a dummy string "Client Index Test."
215  */
216  nr_kvp = keys->ov_vec.v_nr;
217  vlen = strlen(ST_VAL_STRING);
218  for (i = 0; i < nr_kvp; i++) {
219  sprintf(tmp_str,
220  "%" PRIx64 ":%" PRIx64 ":%d",
221  id.u_hi, id.u_lo, start + i);
222 
223  klen = strlen(tmp_str);
224  key_str = m0_alloc(klen);
225  if (key_str == NULL)
226  goto ERROR;
227 
228  val_str = m0_alloc(vlen);
229  if (val_str == NULL)
230  goto ERROR;
231 
232  memcpy(key_str, tmp_str, klen);
233  memcpy(val_str, ST_VAL_STRING, vlen);
234 
235  /* Set bufvec's of keys and vals*/
236  keys->ov_vec.v_count[i] = klen;
237  keys->ov_buf[i] = key_str;
238  vals->ov_vec.v_count[i] = vlen;
239  vals->ov_buf[i] = val_str;
240  }
241 
242  if (prefix) m0_free(prefix);
243  if (tmp_str) m0_free(tmp_str);
244  return 0;
245 
246 ERROR:
247  if (prefix) m0_free(prefix);
248  if (tmp_str) m0_free(tmp_str);
249  if (key_str) m0_free(key_str);
250  if (val_str) m0_free(val_str);
251  return rc;
252 }
253 
254 static int idx_do_insert_kv_pairs(struct m0_uint128 id,
255  struct m0_bufvec *keys,
256  struct m0_bufvec *vals,
257  int *rcs)
258 {
259  int rc;
260  struct m0_op *ops[1] = {NULL};
261  struct m0_idx idx;
262 
264 
265  memset(&idx, 0, sizeof idx);
266  ops[0] = NULL;
267 
269  st_idx_op(&idx, M0_IC_PUT, keys, vals, rcs, 0, &ops[0]);
270 
271  st_op_launch(ops, 1);
272  rc = st_op_wait(ops[0],
274  M0_OS_STABLE),
275  M0_TIME_NEVER);
276  if (rc < 0) return rc;
277 
278  rc = ops[0]->op_rc;
279  /* fini and release */
280  st_op_fini(ops[0]);
281  st_op_free(ops[0]);
283 
284  return rc;
285 }
286 
287 static int idx_insert_kv_pairs(struct m0_uint128 id, int nr_kvp)
288 {
289  int i;
290  int rc = 0;
291  int start;
292  int nr_rounds;
293  int nr_per_round;
294  int nr_to_insert;
295  struct m0_bufvec *keys;
296  struct m0_bufvec *vals;
297  int *rcs;
298 
299  nr_rounds = 1;
300  nr_per_round = nr_kvp / nr_rounds;
301  for (i = 0; i < nr_rounds; i++) {
302  start = i * nr_per_round;
303  if (start + nr_per_round > nr_kvp)
304  nr_to_insert = nr_kvp - start;
305  else
306  nr_to_insert = nr_per_round;
307 
308  /* Allocate bufvec's for keys and vals. */
309  keys = idx_bufvec_alloc(nr_to_insert);
310  vals = idx_bufvec_alloc(nr_to_insert);
311  M0_ALLOC_ARR(rcs, nr_to_insert);
312  if (keys == NULL || vals == NULL || rcs == NULL) {
313  rc = -ENOMEM;
314  goto ERROR;
315  }
316 
317  /* Fill keys and values with some data. */
318  rc = idx_fill_kv_pairs(id, start, keys, vals);
319  if (rc < 0)
320  goto ERROR;
321 
322  /* Do the real job. */
323  rc = idx_do_insert_kv_pairs(id, keys, vals, rcs);
324  if (rc < 0)
325  goto ERROR;
326 
327  idx_bufvec_free(keys);
328  idx_bufvec_free(vals);
329  m0_free0(&rcs);
330  }
331 
332  return rc;
333 
334 ERROR:
335  if (keys) idx_bufvec_free(keys);
336  if (vals) idx_bufvec_free(vals);
337  return rc;
338 }
339 
340 static int idx_create_one(struct m0_uint128 id)
341 {
342  int rc;
343  struct m0_op *ops[1] = {NULL};
344  struct m0_idx idx;
345 
346  memset(&idx, 0, sizeof idx);
347  ops[0] = NULL;
348 
349  /* Set an index creation operation. */
350  st_idx_init(&idx,
351  &st_idx_container.co_realm, &id);
352  st_entity_create(NULL, &idx.in_entity, &ops[0]);
353 
354  /* Launch and wait for op to complete */
355  st_op_launch(ops, 1);
356  rc = st_op_wait(ops[0],
358  M0_OS_STABLE),
359  M0_TIME_NEVER);
360  if (rc < 0) return rc;
361 
362  rc = ops[0]->op_sm.sm_rc;
363  if (rc < 0) return rc;
364  /* fini and release */
365  st_op_fini(ops[0]);
366  st_op_free(ops[0]);
368 
369  return rc;
370 }
371 
372 static int idx_delete_one(struct m0_uint128 id)
373 {
374  int rc;
375  struct m0_op *ops[1] = {NULL};
376  struct m0_idx idx;
377 
378  memset(&idx, 0, sizeof idx);
379  ops[0] = NULL;
380 
381 
382  /* Set an index creation operation. */
384  st_idx_open(&idx.in_entity);
385  st_entity_delete(&idx.in_entity, &ops[0]);
386 
387  /* Launch and wait for op to complete */
388  st_op_launch(ops, 1);
389  rc = st_op_wait(ops[0],
391  M0_OS_STABLE),
392  M0_TIME_NEVER);
393  if (rc < 0) return rc;
394 
395  rc = ops[0]->op_sm.sm_rc;
396  /* fini and release */
397  st_op_fini(ops[0]);
398  st_op_free(ops[0]);
400 
401  return rc;
402 }
403 
404 static int idx_test_prepare(void)
405 {
406  int i;
407  int rc = 0;
408  int nr_kvp;
409  struct m0_uint128 id;
410  struct m0_fid idx_fid;
411 
413 
416  if (deleted_kv_pairs == NULL)
417  return -ENOMEM;
418 
419  for (i = 0; i < ST_MAX_INDEX_NUM; i++) {
420  /* get index's fid. */
421  oid_get(&id);
422  /* Make motr KVS happy */
423  idx_fid = M0_FID_TINIT('x', id.u_hi, id.u_lo);
424  id.u_hi = idx_fid.f_container;
425  id.u_lo = idx_fid.f_key;
426 
427  /* Create an index. */
428  rc = idx_create_one(id);
429  if (rc != 0)
430  break;
431 
432  /* Insert K-V pairs into index. */
433  nr_kvp = get_max_nr_kv_pairs(i);
434  rc = idx_insert_kv_pairs(id, nr_kvp);
435  if (rc < 0)
436  break;
437 
438  test_index_ids[i] = id;
439  }
440 
441  return rc;
442 }
443 
444 #define idx_query_exec(idx_id, opcode, keys, vals, rcs, flag, exp) \
445  do { \
446  int rc; \
447  struct m0_idx idx; \
448  struct m0_op *ops[1] = {NULL}; \
449  \
450  /* Launch DEL query. */ \
451  memset(&idx, 0, sizeof idx); \
452  ops[0] = NULL; \
453  \
454  st_idx_init(&idx, \
455  &st_idx_container.co_realm, &idx_id); \
456  st_idx_op(&idx, opcode, keys, vals, rcs, flag, &ops[0]); \
457  \
458  st_op_launch(ops, 1); \
459  rc = st_op_wait(ops[0], \
460  M0_BITS(M0_OS_FAILED, \
461  M0_OS_STABLE), \
462  M0_TIME_NEVER); \
463  ST_ASSERT_FATAL(rc == 0); \
464  ST_ASSERT_FATAL( \
465  ops[0]->op_sm.sm_state == M0_OS_STABLE);\
466  ST_ASSERT_FATAL(ops[0]->op_rc exp 0); \
467  \
468  /* fini and release */ \
469  st_op_fini(ops[0]); \
470  st_op_free(ops[0]); \
471  st_entity_fini(&idx.in_entity); \
472  } while(0)
473 
474 #define idx_query_exp_success(idx_id, opcode, keys, vals, rcs, flag) \
475  idx_query_exec(idx_id, opcode, keys, vals, rcs, flag, ==)
476 
477 #define idx_query_exp_fail(idx_id, opcode, keys, vals, rcs, flag) \
478  idx_query_exec(idx_id, opcode, keys, vals, rcs, flag, !=)
479 
480 static void idx_query_get(void)
481 {
482  int i;
483  int rc;
484  int idx_door_no;
485  int nr_tests;
486  int nr_kvp;
487  struct m0_op *ops[1] = {NULL};
488  struct m0_idx idx;
489  struct m0_bufvec *keys;
490  struct m0_bufvec *vals;
491  struct m0_uint128 id;
492  int j = 0;
493  int *rcs;
494 
496 
497  nr_kvp = 2;
498  nr_tests = 1;
499  for (i = 0; i < nr_tests; i++) {
500  /* Allocate bufvec's for keys and vals. */
501  keys = idx_bufvec_alloc(nr_kvp);
502  vals = idx_bufvec_alloc(nr_kvp);
503  M0_ALLOC_ARR(rcs, nr_kvp);
504  ST_ASSERT_FATAL(keys != NULL);
505  ST_ASSERT_FATAL(vals != NULL);
506  ST_ASSERT_FATAL(rcs != NULL);
507 
508  /* Fill keys and values with some data. */
509  idx_door_no = generate_random(ST_MAX_INDEX_NUM);
510  id = test_index_ids[idx_door_no];
511  rc = idx_pick_keys(idx_door_no, keys, NULL);
512  ST_ASSERT_FATAL(rc > 0);
513 
514  /* Launch GET query. */
515  memset(&idx, 0, sizeof idx);
516  ops[0] = NULL;
517 
519  st_idx_op(&idx, M0_IC_GET, keys, vals, rcs,
520  0, &ops[0]);
521 
522  st_op_launch(ops, 1);
523  rc = st_op_wait(ops[0],
525  M0_OS_STABLE),
526  M0_TIME_NEVER);
527  ST_ASSERT_FATAL(rc == 0);
528  ST_ASSERT_FATAL(ops[0]->op_sm.sm_state == M0_OS_STABLE);
529  ST_ASSERT_FATAL(ops[0]->op_sm.sm_rc == 0);
530 
531  for(j = 0; j < nr_kvp; j++) {
532  ST_ASSERT_FATAL(rcs[j] == 0);
533  }
534 
535  /* fini and release */
536  st_op_fini(ops[0]);
537  st_op_free(ops[0]);
539 
540  idx_bufvec_free(keys);
541  idx_bufvec_free(vals);
542  m0_free0(&rcs);
543  }
544 }
545 
549 static void idx_query_get_cancel(void)
550 {
551  int i;
552  int rc;
553  int idx_door_no;
554  int nr_tests;
555  int nr_kvp;
556  struct m0_op *ops[1] = {NULL};
557  struct m0_idx idx;
558  struct m0_bufvec *keys;
559  struct m0_bufvec *vals;
560  struct m0_uint128 id;
561  int j = 0;
562  int *rcs;
563 
565 
566  nr_kvp = 2;
567  nr_tests = 1;
568  for (i = 0; i < nr_tests; i++) {
569  /* Allocate bufvec's for keys and vals. */
570  keys = idx_bufvec_alloc(nr_kvp);
571  vals = idx_bufvec_alloc(nr_kvp);
572  M0_ALLOC_ARR(rcs, nr_kvp);
573  ST_ASSERT_FATAL(keys != NULL);
574  ST_ASSERT_FATAL(vals != NULL);
575  ST_ASSERT_FATAL(rcs != NULL);
576 
577  /* Fill keys and values with some data. */
578  idx_door_no = generate_random(ST_MAX_INDEX_NUM);
579  id = test_index_ids[idx_door_no];
580  rc = idx_pick_keys(idx_door_no, keys, NULL);
581  ST_ASSERT_FATAL(rc > 0);
582 
583  /* Launch GET query. */
584  memset(&idx, 0, sizeof idx);
585  ops[0] = NULL;
586 
588  &id);
589  st_idx_op(&idx, M0_IC_GET, keys, vals, rcs,
590  0, &ops[0]);
591 
592  st_op_launch(ops, 1);
593  rc = st_op_wait(ops[0],
595  M0_OS_STABLE),
596  m0_time_from_now(0, 0));
597  if (rc == -ETIMEDOUT) {
598  m0_op_cancel(ops, 1);
599  rc = st_op_wait(ops[0],
601  M0_OS_STABLE),
602  M0_TIME_NEVER);
603  }
604  ST_ASSERT_FATAL(rc == 0);
605  ST_ASSERT_FATAL(ops[0]->op_sm.sm_state ==
606  M0_OS_STABLE);
607  ST_ASSERT_FATAL(ops[0]->op_sm.sm_rc == 0);
608 
609  for(j = 0; j < nr_kvp; j++) {
610  ST_ASSERT_FATAL(rcs[j] == 0);
611  }
612 
613  /* fini and release */
614  st_op_fini(ops[0]);
615  st_op_free(ops[0]);
617 
618  idx_bufvec_free(keys);
619  idx_bufvec_free(vals);
620  m0_free0(&rcs);
621  }
622 }
623 
624 
625 #if 0
626 static void idx_query_get_null(void)
627 {
628  int i;
629  int rc;
630  int idx_door_no;
631  int nr_tests;
632  int nr_kvp;
633  struct m0_op *ops[1] = {NULL};
634  struct m0_idx idx;
635  struct m0_bufvec *keys;
636  struct m0_bufvec *vals;
637  struct m0_uint128 id;
638 
640 
641  nr_kvp = 1;
642  nr_tests = 1;
643  for (i = 0; i < nr_tests; i++) {
644  /* Allocate bufvec's for keys and vals. */
645  keys = idx_bufvec_alloc(nr_kvp);
646  vals = idx_bufvec_alloc(nr_kvp);
647  ST_ASSERT_FATAL(keys != NULL);
648  ST_ASSERT_FATAL(vals != NULL);
649 
650  idx_door_no = generate_random(ST_MAX_INDEX_NUM);
651  id = test_index_ids[idx_door_no];
652 
653  keys->ov_buf[0] = NULL;
654  keys->ov_vec.v_count[0] = 0;
655 
656  /* Launch GET query. */
657  memset(&idx, 0, sizeof idx);
658  ops[0] = NULL;
659 
661  st_idx_op(&idx, M0_IC_GET, keys, vals, rcs, &ops[0]);
662 
663  st_op_launch(ops, 1);
664  rc = st_op_wait(ops[0],
666  M0_OS_STABLE),
667  M0_TIME_NEVER);
668  ST_ASSERT_FATAL(rc == 0);
669  ST_ASSERT_FATAL(ops[0]->op_sm.sm_state != M0_OS_STABLE);
670  ST_ASSERT_FATAL(ops[0]->op_sm.sm_rc != 0);
671 
672  /* fini and release */
673  st_op_fini(ops[0]);
674  st_op_free(ops[0]);
675  st_entity_fini(&idx.in_entity);
676 
677  idx_bufvec_free(keys);
678  idx_bufvec_free(vals);
679  }
680 }
681 #endif
682 
683 #ifndef __KERNEL__
684 static void idx_query_get_nonexist(void)
685 {
686  int i;
687  int rc;
688  int idx_door_no;
689  int nr_kvp;
690  struct m0_op *ops[1] = {NULL};
691  struct m0_idx idx;
692  struct m0_bufvec *keys;
693  struct m0_bufvec *vals;
694  struct m0_uint128 id;
695  int *rcs;
696 
698 
699  /* Allocate bufvec's for keys and vals. */
700  nr_kvp = 2;
701  keys = idx_bufvec_alloc(nr_kvp);
702  vals = idx_bufvec_alloc(nr_kvp);
703  ST_ASSERT_FATAL(keys != NULL);
704  ST_ASSERT_FATAL(vals != NULL);
705 
706  M0_ALLOC_ARR(rcs, nr_kvp);
707  /* Fill keys and values with some data. */
708  idx_door_no = generate_random(ST_MAX_INDEX_NUM);
709  id = test_index_ids[idx_door_no];
710  rc = idx_pick_keys(idx_door_no, keys, NULL);
711 
712  for (i = 0; i < keys->ov_vec.v_nr; i++) {
713  keys->ov_vec.v_count[i] = 10;
714  memcpy((char *)(keys->ov_buf[i]), "nonexistkv", 10);
715  }
716 
717  /* Launch GET query. */
718  memset(&idx, 0, sizeof idx);
719  ops[0] = NULL;
720 
722  st_idx_op(&idx, M0_IC_GET, keys, vals, rcs, 0, &ops[0]);
723 
724  st_op_launch(ops, 1);
725  rc = st_op_wait(ops[0],
727  M0_OS_STABLE),
728  M0_TIME_NEVER);
729  ST_ASSERT_FATAL(rc == 0);
730  ST_ASSERT_FATAL(ops[0]->op_sm.sm_state == M0_OS_STABLE);
731  ST_ASSERT_FATAL(ops[0]->op_sm.sm_rc == 0);
732 
733  for(i = 0; i < nr_kvp; i++) {
734  ST_ASSERT_FATAL(rcs[i] != 0);
735  }
736 
737  /* fini and release */
738  st_op_fini(ops[0]);
739  st_op_free(ops[0]);
741 
742  idx_bufvec_free(keys);
743  idx_bufvec_free(vals);
744  m0_free0(&rcs);
745 }
746 
748 {
749  int i;
750  int rc;
751  int idx_door_no;
752  int nr_kvp;
753  struct m0_op *ops[1] = {NULL};
754  struct m0_idx idx;
755  struct m0_bufvec *keys;
756  struct m0_bufvec *vals;
757  struct m0_uint128 id;
758  struct m0_fid idx_fid;
759  int *rcs;
760 
762 
763  oid_get(&id);
764  /* Make motr kvs happy*/
765  idx_fid = M0_FID_TINIT('i', id.u_hi, id.u_lo);
766  id.u_hi = idx_fid.f_container;
767  id.u_lo = idx_fid.f_key;
768 
769  /* Allocate bufvec's for keys and vals. */
770  nr_kvp = 2;
771  keys = idx_bufvec_alloc(nr_kvp);
772  vals = idx_bufvec_alloc(nr_kvp);
773  M0_ALLOC_ARR(rcs, nr_kvp);
774  ST_ASSERT_FATAL(keys != NULL);
775  ST_ASSERT_FATAL(vals != NULL);
776  ST_ASSERT_FATAL(rcs != NULL);
777 
778  /* Fill keys and values with some data. */
779  idx_door_no = generate_random(ST_MAX_INDEX_NUM);
780  idx_pick_keys(idx_door_no, keys, NULL);
781 
782  for (i = 0; i < keys->ov_vec.v_nr; i++) {
783  keys->ov_vec.v_count[i] = 10;
784  memcpy((char *)(keys->ov_buf[i]), "nonexistkv", 10);
785  }
786 
787  /* Launch GET query. */
788  memset(&idx, 0, sizeof idx);
789  ops[0] = NULL;
790 
792  st_idx_op(&idx, M0_IC_GET, keys, vals, rcs, 0, &ops[0]);
793 
794  st_op_launch(ops, 1);
795  rc = st_op_wait(ops[0],
797  M0_OS_STABLE),
798  M0_TIME_NEVER);
799  ST_ASSERT_FATAL(rc == 0);
800  ST_ASSERT_FATAL(ops[0]->op_sm.sm_state == M0_OS_STABLE);
801  ST_ASSERT_FATAL(ops[0]->op_rc != 0);
802 
803  /* fini and release */
804  st_op_fini(ops[0]);
805  st_op_free(ops[0]);
807 
808  idx_bufvec_free(keys);
809  idx_bufvec_free(vals);
810  m0_free0(&rcs);
811 }
812 
813 #endif
814 
815 static void idx_query_del(void)
816 {
817  int i;
818  int j;
819  int rc;
820  int idx_door_no;
821  int nr_tests;
822  int nr_kvp;
823  int *key_no_arr;
824  int key_no;
825  struct m0_bufvec *keys;
826  struct m0_uint128 id;
827  int *rcs;
828 
830 
831  nr_kvp = 2;
832  nr_tests = 1;
833 
834  key_no_arr = m0_alloc(nr_kvp * sizeof(*key_no_arr));
835  if (key_no_arr == NULL)
836  return;
837 
838  M0_ALLOC_ARR(rcs, nr_kvp);
839  for (i = 0; i < nr_tests; i++) {
840  /* Allocate bufvec's for keys and vals. */
841  keys = idx_bufvec_alloc(nr_kvp);
842  ST_ASSERT_FATAL(keys != NULL);
843 
844  /* Pick those keys to be deleted. */
845  idx_door_no = generate_random(ST_MAX_INDEX_NUM);
846  id = test_index_ids[idx_door_no];
847  rc = idx_pick_keys(idx_door_no, keys, key_no_arr);
848  if (rc < 0)
849  goto BUFVEC_FREE;
850 
851  /* Launch DEL query. */
852  idx_query_exp_success(id, M0_IC_DEL, keys, NULL, rcs, 0);
853 
854  for (j = 0; j < nr_kvp; j++) {
855  key_no = idx_door_no * ST_LARGE_KV_PAIR_NUM +
856  key_no_arr[j];
857  deleted_kv_pairs[key_no] = true;
858  }
859 BUFVEC_FREE:
860  idx_bufvec_free(keys);
861  }
862  m0_free(key_no_arr);
863 }
864 
865 static void idx_query_next(void)
866 {
867  int i;
868  int idx_door_no;
869  int nr_rounds = 1;
870  int nr_kvp;
871  int last_key_len = 0;
872  void *last_key = NULL;
873  struct m0_bufvec *keys;
874  struct m0_bufvec *vals;
875  struct m0_uint128 id;
876  int *rcs;
877 
879 
880  for (i = 0; i < nr_rounds; i++) {
881  /* Allocate bufvec's for keys and vals. */
882  nr_kvp = 2; /* or a random number. */
883  keys = idx_bufvec_alloc(nr_kvp);
884  ST_ASSERT_FATAL(keys != NULL);
885 
886  vals = idx_bufvec_alloc(nr_kvp);
887  ST_ASSERT_FATAL(vals != NULL);
888 
889  M0_ALLOC_ARR(rcs, nr_kvp);
890  /* Launch NEXT query. */
891  idx_door_no = generate_random(ST_MAX_INDEX_NUM);
892  id = test_index_ids[idx_door_no];
893  keys->ov_buf[0] = last_key;
894  keys->ov_vec.v_count[0] = last_key_len;
895  idx_query_exp_success(id, M0_IC_NEXT, keys, vals, rcs, 0);
896 
897  /* Extract the last key for next round. */
898  if (i == nr_rounds - 1)
899  goto FREE_BUFVEC;
900 
901  if (keys->ov_buf[nr_kvp - 1] == NULL)
902  break;
903 
904  if (last_key != NULL)
905  m0_free(last_key);
906  last_key_len = keys->ov_vec.v_count[nr_kvp - 1];
907  last_key = m0_alloc(last_key_len);
908  memcpy(last_key, keys->ov_buf[nr_kvp - 1], last_key_len);
909 
910 FREE_BUFVEC:
911  idx_bufvec_free(keys);
912  idx_bufvec_free(vals);
913  m0_free0(&rcs);
914  }
915 }
916 
918 {
919  int idx_door_no;
920  int nr_kvp;
921  int last_key_len = 0;
922  int stored_key_len = 0;
923  void *last_key = NULL;
924  void *stored_key = NULL;
925  struct m0_bufvec *keys;
926  struct m0_bufvec *vals;
927  struct m0_uint128 id;
928  int *rcs;
929 
931 
933  nr_kvp = 2;
934  keys = idx_bufvec_alloc(nr_kvp);
935  ST_ASSERT_FATAL(keys != NULL);
936 
937  vals = idx_bufvec_alloc(nr_kvp);
938  ST_ASSERT_FATAL(vals != NULL);
939 
940  M0_ALLOC_ARR(rcs, nr_kvp);
941  /* Launch NEXT query. */
942  idx_door_no = generate_random(ST_MAX_INDEX_NUM);
943  id = test_index_ids[idx_door_no];
944  keys->ov_buf[0] = last_key;
945  keys->ov_vec.v_count[0] = last_key_len;
946  idx_query_exp_success(id, M0_IC_NEXT, keys, vals, rcs,
948 
949  ST_ASSERT_FATAL(keys->ov_buf[nr_kvp - 1] != NULL)
950 
951 
952  last_key_len = keys->ov_vec.v_count[nr_kvp - 1];
953  last_key = m0_alloc(last_key_len);
954 
956  stored_key_len = last_key_len;
957  stored_key = m0_alloc(last_key_len);
958  memcpy(last_key, keys->ov_buf[nr_kvp - 1], last_key_len);
959  memcpy(stored_key, keys->ov_buf[nr_kvp - 1], last_key_len);
960 
961  idx_bufvec_free(keys);
962  idx_bufvec_free(vals);
963  m0_free0(&rcs);
964 
966  nr_kvp = 2;
967  keys = idx_bufvec_alloc(nr_kvp);
968  ST_ASSERT_FATAL(keys != NULL);
969 
970  vals = idx_bufvec_alloc(nr_kvp);
971  ST_ASSERT_FATAL(vals != NULL);
972 
973  M0_ALLOC_ARR(rcs, nr_kvp);
974  /* Launch NEXT query. */
975  idx_door_no = generate_random(ST_MAX_INDEX_NUM);
976  id = test_index_ids[idx_door_no];
977  keys->ov_buf[0] = last_key;
978  keys->ov_vec.v_count[0] = last_key_len;
979  idx_query_exp_success(id, M0_IC_NEXT, keys, vals, rcs,
981 
982  ST_ASSERT_FATAL(keys->ov_buf[nr_kvp - 1] != NULL)
983 
984 
985  if(keys->ov_vec.v_count[0] == stored_key_len) {
986  ST_ASSERT_FATAL(memcmp(stored_key,
987  keys->ov_buf[0], stored_key_len) != 0);
988  }
989 
990  m0_free(stored_key);
991  idx_bufvec_free(keys);
992  idx_bufvec_free(vals);
993  m0_free0(&rcs);
994 
995 }
996 
997 static void mock_op_cb_stable(struct m0_op *op)
998 {
999  int *val;
1000 
1001  val = (int *)op->op_datum;
1002  *val = 'S';
1003 }
1004 
1005 static void mock_op_cb_failed(struct m0_op *op)
1006 {
1007  int *val;
1008 
1009  val = (int *)op->op_datum;
1010  *val = 'F';
1011 }
1012 
1013 
1014 /* Setup callbacks instead of using m0_op_wait. */
1015 static void idx_query_callbacks(void)
1016 {
1017  int rc;
1018  int val = 0;
1019  struct m0_uint128 id;
1020  struct m0_fid idx_fid;
1021  struct m0_op *ops[1] = {NULL};
1022  struct m0_idx idx;
1023  struct m0_op_ops cbs;
1024 
1025  /* get index's fid. */
1026  oid_get(&id);
1027  /* Make motr DIX happy. */
1028  idx_fid = M0_FID_TINIT('x', id.u_hi, id.u_lo);
1029  id.u_hi = idx_fid.f_container;
1030  id.u_lo = idx_fid.f_key;
1031 
1032  /*
1033  * Set callbacks for operations.
1034  * ocb_executed is not supported (see comments in motr/client.h)
1035  */
1036  cbs.oop_executed = NULL;
1039 
1040  /* Set an index creation operation. */
1041  ops[0] = NULL;
1042  memset(&idx, 0, sizeof idx);
1043 
1044  st_idx_init(&idx,
1045  &st_idx_container.co_realm, &id);
1046  st_entity_create(NULL, &idx.in_entity, &ops[0]);
1047 
1048  /* Launch and wait for op to complete */
1049  ops[0]->op_datum = (void *)&val;
1050  m0_op_setup(ops[0], &cbs, 0);
1051  st_op_launch(ops, 1);
1052 
1053  /* Test callback functions for OS_STABLE*/
1054  rc = st_op_wait(ops[0],
1056  M0_OS_STABLE),
1057  M0_TIME_NEVER);
1058  if (rc == 0) {
1059  if (ops[0]->op_sm.sm_state == M0_OS_STABLE)
1060  ST_ASSERT_FATAL(val == 'S')
1061  else if (ops[0]->op_sm.sm_state == M0_OS_FAILED)
1062  ST_ASSERT_FATAL(val == 'F')
1063  }
1064 
1065  idx_delete_one(id);
1066  /* fini and release */
1067  st_op_fini(ops[0]);
1068  st_op_free(ops[0]);
1069  st_entity_fini(&idx.in_entity);
1070 }
1071 
1072 static void idx_query_empty_next(void)
1073 {
1074  int rc = 0;
1075  struct m0_uint128 id;
1076  struct m0_fid idx_fid;
1077  struct m0_bufvec *keys;
1078  struct m0_bufvec *vals;
1079  int *rcs;
1080  int nr_kvp = 1; /* or a random number. */
1081 
1082  oid_get(&id);
1083  /* Make motr kvs happy*/
1084  idx_fid = M0_FID_TINIT('x', id.u_hi, id.u_lo);
1085  id.u_hi = idx_fid.f_container;
1086  id.u_lo = idx_fid.f_key;
1087 
1088  /* Create an index. */
1089  rc = idx_create_one(id);
1090  ST_ASSERT_FATAL(rc == 0);
1091 
1092  /* Allocate bufvec's for keys and vals. */
1093  keys = idx_bufvec_alloc(nr_kvp);
1094  ST_ASSERT_FATAL(keys != NULL);
1095 
1096  vals = idx_bufvec_alloc(nr_kvp);
1097  ST_ASSERT_FATAL(vals != NULL);
1098 
1099  /* Launch NEXT query. */
1100  keys->ov_buf[0] = NULL;
1101  keys->ov_vec.v_count[0] = 0;
1102 
1103  M0_ALLOC_ARR(rcs, nr_kvp);
1104  idx_query_exp_success(id, M0_IC_NEXT, keys, vals, rcs, 0);
1105  ST_ASSERT_FATAL(keys->ov_vec.v_nr == nr_kvp && keys->ov_buf[0] == NULL);
1106 
1107  rc = idx_delete_one(id);
1108  ST_ASSERT_FATAL(rc == 0);
1109 
1110  /* fini and release */
1111  idx_bufvec_free(keys);
1112  idx_bufvec_free(vals);
1113  m0_free0(&rcs);
1114 }
1115 
1117 {
1118  struct m0_uint128 id;
1119  struct m0_fid idx_fid;
1120  struct m0_bufvec *keys;
1121  struct m0_bufvec *vals;
1122  int *rcs;
1123  int nr_kvp = 1; /* or a random number. */
1124 
1125  oid_get(&id);
1126  /* Make motr kvs happy*/
1127  idx_fid = M0_FID_TINIT('x', id.u_hi, id.u_lo);
1128  id.u_hi = idx_fid.f_container;
1129  id.u_lo = idx_fid.f_key;
1130 
1131  /* Allocate bufvec's for keys and vals. */
1132  keys = idx_bufvec_alloc(nr_kvp);
1133  ST_ASSERT_FATAL(keys != NULL);
1134 
1135  vals = idx_bufvec_alloc(nr_kvp);
1136  ST_ASSERT_FATAL(vals != NULL);
1137 
1138  M0_ALLOC_ARR(rcs, nr_kvp);
1139  /* Launch NEXT query. */
1140  keys->ov_buf[0] = NULL;
1141  keys->ov_vec.v_count[0] = 0;
1142 
1143  idx_query_exp_fail(id, M0_IC_NEXT, keys, vals, rcs, 0);
1144  ST_ASSERT_FATAL(keys->ov_vec.v_nr == nr_kvp && keys->ov_buf[0] == NULL);
1145 
1146  /* fini and release */
1147  idx_bufvec_free(keys);
1148  idx_bufvec_free(vals);
1149  m0_free0(&rcs);
1150 
1151 }
1152 
1153 static void idx_query_drop_index(void)
1154 {
1155  int rc = 0;
1156  struct m0_uint128 id;
1157  struct m0_fid idx_fid;
1158  struct m0_bufvec *keys;
1159  struct m0_bufvec *vals;
1160  int *rcs;
1161  int nr_kvp = 1; /* or a random number. */
1162 
1163  oid_get(&id);
1164  /* Make motr kvs happy*/
1165  idx_fid = M0_FID_TINIT('x', id.u_hi, id.u_lo);
1166  id.u_hi = idx_fid.f_container;
1167  id.u_lo = idx_fid.f_key;
1168 
1169  /* Create an index. */
1170  rc = idx_create_one(id);
1171  ST_ASSERT_FATAL(rc == 0);
1172 
1173  /* Allocate bufvec's for keys and vals. */
1174  keys = idx_bufvec_alloc(nr_kvp);
1175  ST_ASSERT_FATAL(keys != NULL);
1176 
1177  vals = idx_bufvec_alloc(nr_kvp);
1178  ST_ASSERT_FATAL(vals != NULL);
1179 
1180  M0_ALLOC_ARR(rcs, nr_kvp);
1181  idx_fill_kv_pairs(id, 0, keys, vals);
1182 
1183  rc = idx_do_insert_kv_pairs(id, keys, vals, rcs);
1184  ST_ASSERT_FATAL(rc == 0);
1185 
1186  rc = idx_delete_one(id);
1187  ST_ASSERT_FATAL(rc == 0);
1188 
1189  /* Launch NEXT query. */
1190  keys->ov_buf[0] = NULL;
1191  keys->ov_vec.v_count[0] = 0;
1192 
1193  idx_query_exp_fail(id, M0_IC_NEXT, keys, vals, rcs, 0);
1194  ST_ASSERT_FATAL(keys->ov_vec.v_nr == nr_kvp && keys->ov_buf[0] == NULL);
1195 
1196  /* fini and release */
1197  idx_bufvec_free(keys);
1198  idx_bufvec_free(vals);
1199  m0_free0(&rcs);
1200 }
1201 
1202 /* This test case is inconsistent.
1203  * Cassandra and KVS behaviour in this case different.
1204  */
1205 #if 0
1206 static void idx_query_put_duplicate(void)
1207 {
1208  int rc = 0;
1209  struct m0_uint128 id;
1210  struct m0_fid idx_fid;
1211  struct m0_bufvec *keys;
1212  struct m0_bufvec *vals;
1213 
1214  int nr_kvp = 1; /* or a random number. */
1215 
1216  oid_get(&id);
1217  /* Make motr kvs happy*/
1218  idx_fid = M0_FID_TINIT('i', id.u_hi, id.u_lo);
1219  id.u_hi = idx_fid.f_container;
1220  id.u_lo = idx_fid.f_key;
1221 
1222  /* Create an index. */
1223  rc = idx_create_one(id);
1224  ST_ASSERT_FATAL(rc == 0);
1225 
1226  /* Allocate bufvec's for keys and vals. */
1227  keys = idx_bufvec_alloc(nr_kvp);
1228  ST_ASSERT_FATAL(keys != NULL);
1229 
1230  vals = idx_bufvec_alloc(nr_kvp);
1231  ST_ASSERT_FATAL(vals != NULL);
1232 
1233  idx_fill_kv_pairs(id, 0, keys, vals);
1234 
1235  rc = idx_do_insert_kv_pairs(id, keys, vals);
1236  ST_ASSERT_FATAL(rc == 0);
1237 
1238  /* Try to insert the same kv pair again */
1239  rc = idx_do_insert_kv_pairs(id, keys, vals);
1240  ST_ASSERT_FATAL(rc != 0);
1241 
1242  rc = idx_delete_one(id);
1243  ST_ASSERT_FATAL(rc == 0);
1244  /* fini and release */
1245  idx_bufvec_free(keys);
1246  idx_bufvec_free(vals);
1247 }
1248 #endif
1249 
1251 {
1252  int rc = 0;
1253  struct m0_uint128 id;
1254  struct m0_fid idx_fid;
1255  struct m0_bufvec *keys;
1256  struct m0_bufvec *vals;
1257  int *rcs;
1258 
1259  int nr_kvp = 1; /* or a random number. */
1260 
1261  oid_get(&id);
1262  /* Make motr kvs happy*/
1263  idx_fid = M0_FID_TINIT('i', id.u_hi, id.u_lo);
1264  id.u_hi = idx_fid.f_container;
1265  id.u_lo = idx_fid.f_key;
1266 
1267  /* Allocate bufvec's for keys and vals. */
1268  keys = idx_bufvec_alloc(nr_kvp);
1269  ST_ASSERT_FATAL(keys != NULL);
1270 
1271  vals = idx_bufvec_alloc(nr_kvp);
1272  ST_ASSERT_FATAL(vals != NULL);
1273 
1274  M0_ALLOC_ARR(rcs, nr_kvp);
1275  idx_fill_kv_pairs(id, 0, keys, vals);
1276 
1277  rc = idx_do_insert_kv_pairs(id, keys, vals, rcs);
1278  ST_ASSERT_FATAL(rc != 0);
1279 
1280  /* fini and release */
1281  idx_bufvec_free(keys);
1282  idx_bufvec_free(vals);
1283  m0_free0(&rcs);
1284 }
1285 
1289 static int st_idx_suite_init(void)
1290 {
1291  int rc = 0;
1292 
1293  /*
1294  * Retrieve the uber realm. We don't need to open this,
1295  * as realms are not actually implemented yet
1296  */
1298  NULL, &M0_UBER_REALM,
1299  st_get_instance());
1301 
1302  if (rc != 0) {
1303  console_printf("Failed to open uber realm\n");
1304  goto EXIT;
1305  }
1306 
1307  /* Create and populate the indices for query tests. */
1308  rc = idx_test_prepare();
1309 
1310 EXIT:
1311  return rc;
1312 }
1313 
1317 static int st_idx_suite_fini(void)
1318 {
1319  return 0;
1320 }
1321 
1323  .ss_name = "idx_st",
1324  .ss_init = st_idx_suite_init,
1325  .ss_fini = st_idx_suite_fini,
1326  .ss_tests = {
1327  { "idx_query_get",
1328  &idx_query_get },
1329  { "idx_query_get_cancel",
1331 #if 0
1332  { "idx_query_get_null",
1333  &idx_query_get_null },
1334  { "idx_query_put_duplicate",
1335  &idx_query_put_duplicate },
1336 #endif
1337  { "idx_query_put_not_existent_index",
1339 #ifndef __KERNEL__
1340  { "idx_query_get_nonexist",
1342  { "idx_query_get_non_existing_index",
1344 #endif
1345  { "idx_query_del",
1346  &idx_query_del },
1347  { "idx_query_next",
1348  &idx_query_next },
1349  { "idx_query_next_exclude_start",
1351  { "idx_query_empty_next",
1353  { "idx_query_next_not_exist_index",
1355  { "idx_query_drop_index",
1357  { "idx_query_callbacks",
1359  { NULL, NULL }
1360  }
1361 };
1362 
1363 #undef M0_TRACE_SUBSYSTEM
1364 
1365 /*
1366  * Local variables:
1367  * c-indentation-style: "K&R"
1368  * c-basic-offset: 8
1369  * tab-width: 8
1370  * fill-column: 80
1371  * scroll-step: 1
1372  * End:
1373  */
uint64_t id
Definition: cob.h:2380
void st_idx_init(struct m0_idx *idx, struct m0_realm *parent, const struct m0_uint128 *id)
Definition: api.c:56
static size_t nr
Definition: dump.c:1505
int st_entity_create(struct m0_fid *pool, struct m0_entity *entity, struct m0_op **op)
Definition: api.c:71
void st_idx_open(struct m0_entity *entity)
Definition: api.c:176
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
Definition: client.h:835
void st_op_free(struct m0_op *op)
Definition: api.c:147
#define ST_VAL_STRING
Definition: idx.c:33
static int idx_do_insert_kv_pairs(struct m0_uint128 id, struct m0_bufvec *keys, struct m0_bufvec *vals, int *rcs)
Definition: idx.c:254
#define NULL
Definition: misc.h:38
Definition: idx_mock.c:52
static int idx_delete_one(struct m0_uint128 id)
Definition: idx.c:372
static int st_idx_suite_fini(void)
Definition: idx.c:1317
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
static void idx_query_del(void)
Definition: idx.c:815
void(* oop_executed)(struct m0_op *op)
Definition: client.h:909
struct st_suite st_suite_idx
Definition: idx.c:1322
struct m0_vec ov_vec
Definition: vec.h:147
static struct m0_uint128 prefix
Definition: extmap.c:45
static int get_max_nr_kv_pairs(int idx_door_no)
Definition: idx.c:47
uint64_t u_lo
Definition: types.h:58
#define M0_BITS(...)
Definition: misc.h:236
int st_idx_op(struct m0_idx *idx, enum m0_idx_opcode opcode, struct m0_bufvec *keys, struct m0_bufvec *vals, int *rcs, int flag, struct m0_op **op)
Definition: api.c:113
static struct m0_container st_idx_container
Definition: idx.c:43
const struct m0_uint128 M0_UBER_REALM
Definition: client.c:85
#define ST_ASSERT_FATAL(a)
Definition: st_assert.h:31
void ** ov_buf
Definition: vec.h:149
#define PRIx64
Definition: types.h:61
static void idx_query_next_not_exist_index(void)
Definition: idx.c:1116
op
Definition: libdemo.c:64
static void mock_op_cb_stable(struct m0_op *op)
Definition: idx.c:997
static int idx_create_one(struct m0_uint128 id)
Definition: idx.c:340
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
Definition: vec.c:395
struct m0_entity in_entity
Definition: client.h:836
int i
Definition: dir.c:1033
struct m0_realm co_realm
Definition: client.h:881
static void idx_query_callbacks(void)
Definition: idx.c:1015
static int idx_pick_keys(int idx_door_no, struct m0_bufvec *keys, int *key_no_arr)
Definition: idx.c:112
Definition: client.h:641
static int st_idx_suite_init(void)
Definition: idx.c:1289
static struct m0_uint128 test_index_ids[ST_MAX_INDEX_NUM]
Definition: idx.c:44
static bool is_kv_pair_deleted(int idx_door_no, int key_no)
Definition: idx.c:104
static struct m0_bufvec * idx_bufvec_alloc(int nr)
Definition: idx.c:80
#define ERROR(_fmt,...)
Definition: m0hsm_api.c:66
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
static int idx_insert_kv_pairs(struct m0_uint128 id, int nr_kvp)
Definition: idx.c:287
void(* oop_stable)(struct m0_op *op)
Definition: client.h:911
static void idx_query_get_cancel(void)
Definition: idx.c:549
void st_container_init(struct m0_container *con, struct m0_realm *parent, const struct m0_uint128 *id, struct m0_client *instance)
Definition: api.c:34
struct m0_entity re_entity
Definition: client.h:871
int oid_get(struct m0_uint128 *oid)
Definition: oid.c:373
#define FAIL
#define m0_free0(pptr)
Definition: memory.h:77
Definition: st.h:83
static void idx_query_empty_next(void)
Definition: idx.c:1072
uint64_t u_hi
Definition: types.h:57
void * m0_alloc(size_t size)
Definition: memory.c:126
uint64_t f_container
Definition: fid.h:39
static void idx_query_drop_index(void)
Definition: idx.c:1153
uint32_t v_nr
Definition: vec.h:51
int32_t sm_rc
Definition: sm.h:336
static void idx_query_next(void)
Definition: idx.c:865
m0_bcount_t * v_count
Definition: vec.h:53
void console_printf(const char *fmt,...)
Definition: st_misc.c:155
void(* oop_failed)(struct m0_op *op)
Definition: client.h:910
static void mem_free(const struct m0_be_btree *btree, struct m0_be_tx *tx, void *ptr)
Definition: btree.c:102
void m0_op_cancel(struct m0_op **op, uint32_t nr)
Definition: client.c:639
static void idx_query_put_not_existent_index(void)
Definition: idx.c:1250
static int idx_test_prepare(void)
Definition: idx.c:404
static void idx_query_get(void)
Definition: idx.c:480
static void mock_op_cb_failed(struct m0_op *op)
Definition: idx.c:1005
Definition: fid.h:38
static void idx_query_get_non_existing_index(void)
Definition: idx.c:747
uint64_t f_key
Definition: fid.h:40
static void idx_query_get_nonexist(void)
Definition: idx.c:684
m0_time_t m0_time_from_now(uint64_t secs, long ns)
Definition: time.c:96
struct m0_client * st_get_instance()
Definition: st.c:57
#define M0_CLIENT_THREAD_ENTER
static int start(struct m0_fom *fom)
Definition: trigger_fom.c:321
void st_op_launch(struct m0_op **op, uint32_t nr)
Definition: api.c:129
void st_entity_fini(struct m0_entity *entity)
Definition: api.c:94
uint32_t generate_random(uint32_t max)
Definition: st_misc.c:164
const char * ss_name
Definition: st.h:85
static void idx_bufvec_free(struct m0_bufvec *bv)
Definition: idx.c:64
int st_entity_delete(struct m0_entity *entity, struct m0_op **op)
Definition: api.c:83
static bool * deleted_kv_pairs
Definition: idx.c:45
static int idx_fill_kv_pairs(struct m0_uint128 id, int start, struct m0_bufvec *keys, struct m0_bufvec *vals)
Definition: idx.c:189
struct m0_sm en_sm
Definition: client.h:732
#define idx_query_exp_success(idx_id, opcode, keys, vals, rcs, flag)
Definition: idx.c:474
int type
Definition: dir.c:1031
struct m0_fom_ops ops
Definition: io_foms.c:623
void m0_free(void *data)
Definition: memory.c:146
int32_t st_op_wait(struct m0_op *op, uint64_t bits, m0_time_t to)
Definition: api.c:136
void st_op_fini(struct m0_op *op)
Definition: api.c:142
int32_t rc
Definition: trigger_fop.h:47
static void idx_query_next_exclude_start(void)
Definition: idx.c:917
Definition: vec.h:145
#define idx_query_exp_fail(idx_id, opcode, keys, vals, rcs, flag)
Definition: idx.c:477
void m0_op_setup(struct m0_op *op, const struct m0_op_ops *cbs, m0_time_t linger)
Definition: client.c:908