| /* Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #define C_TESTLUCY_TESTSERIESMATCHER |
| #define TESTLUCY_USE_SHORT_NAMES |
| #include "Lucy/Util/ToolSet.h" |
| |
| #include "Clownfish/TestHarness/TestBatchRunner.h" |
| #include "Lucy/Test.h" |
| #include "Lucy/Test/Search/TestSeriesMatcher.h" |
| #include "Lucy/Search/BitVecMatcher.h" |
| #include "Lucy/Search/SeriesMatcher.h" |
| |
| TestSeriesMatcher* |
| TestSeriesMatcher_new() { |
| return (TestSeriesMatcher*)Class_Make_Obj(TESTSERIESMATCHER); |
| } |
| |
| static SeriesMatcher* |
| S_make_series_matcher(I32Array *doc_ids, I32Array *offsets, int32_t doc_max) { |
| size_t num_doc_ids = I32Arr_Get_Size(doc_ids); |
| size_t num_matchers = I32Arr_Get_Size(offsets); |
| Vector *matchers = Vec_new(num_matchers); |
| size_t tick = 0; |
| |
| // Divvy up doc_ids by segment into BitVectors. |
| for (size_t i = 0; i < num_matchers; i++) { |
| int32_t offset = I32Arr_Get(offsets, i); |
| int32_t max = i == num_matchers - 1 |
| ? doc_max + 1 |
| : I32Arr_Get(offsets, i + 1); |
| BitVector *bit_vec = BitVec_new((size_t)(max - offset)); |
| while (tick < num_doc_ids) { |
| int32_t doc_id = I32Arr_Get(doc_ids, tick); |
| if (doc_id > max) { break; } |
| else { tick++; } |
| BitVec_Set(bit_vec, (size_t)(doc_id - offset)); |
| } |
| Vec_Push(matchers, (Obj*)BitVecMatcher_new(bit_vec)); |
| DECREF(bit_vec); |
| } |
| |
| SeriesMatcher *series_matcher = SeriesMatcher_new(matchers, offsets); |
| DECREF(matchers); |
| return series_matcher; |
| } |
| |
| static I32Array* |
| S_generate_match_list(int32_t first, int32_t max, int32_t doc_inc) { |
| int32_t count = (max - first + doc_inc - 1) / doc_inc; |
| int32_t *doc_ids = (int32_t*)MALLOCATE((size_t)count * sizeof(int32_t)); |
| int32_t doc_id = first; |
| int32_t i = 0; |
| |
| for (; doc_id < max; doc_id += doc_inc, i++) { |
| doc_ids[i] = doc_id; |
| } |
| if (i != count) { THROW(ERR, "Screwed up somehow: %i32 %i32", i, count); } |
| |
| return I32Arr_new_steal(doc_ids, (size_t)count); |
| } |
| |
| static void |
| S_do_test_matrix(TestBatchRunner *runner, int32_t doc_max, int32_t first_doc_id, |
| int32_t doc_inc, int32_t offset_inc) { |
| I32Array *doc_ids |
| = S_generate_match_list(first_doc_id, doc_max, doc_inc); |
| I32Array *offsets |
| = S_generate_match_list(0, doc_max, offset_inc); |
| SeriesMatcher *series_matcher |
| = S_make_series_matcher(doc_ids, offsets, doc_max); |
| size_t num_in_agreement = 0; |
| int32_t got; |
| |
| while (0 != (got = SeriesMatcher_Next(series_matcher))) { |
| if (got != I32Arr_Get(doc_ids, num_in_agreement)) { break; } |
| num_in_agreement++; |
| } |
| TEST_UINT_EQ(runner, num_in_agreement, I32Arr_Get_Size(doc_ids), |
| "doc_max=%d first_doc_id=%d doc_inc=%d offset_inc=%d", |
| doc_max, first_doc_id, doc_inc, offset_inc); |
| |
| DECREF(doc_ids); |
| DECREF(offsets); |
| DECREF(series_matcher); |
| } |
| |
| static void |
| test_matrix(TestBatchRunner *runner) { |
| int32_t doc_max_nums[] = { 10, 100, 1000, 0 }; |
| int32_t first_doc_ids[] = { 1, 2, 10, 0 }; |
| int32_t doc_inc_nums[] = { 20, 13, 9, 4, 2, 0 }; |
| int32_t offset_inc_nums[] = { 7, 29, 71, 0 }; |
| int32_t a, b, c, d; |
| |
| for (a = 0; doc_max_nums[a] != 0; a++) { |
| for (b = 0; first_doc_ids[b] != 0; b++) { |
| for (c = 0; doc_inc_nums[c] != 0; c++) { |
| for (d = 0; offset_inc_nums[d] != 0; d++) { |
| int32_t doc_max = doc_max_nums[a]; |
| int32_t first_doc_id = first_doc_ids[b]; |
| int32_t doc_inc = doc_inc_nums[c]; |
| int32_t offset_inc = offset_inc_nums[d]; |
| if (first_doc_id > doc_max) { |
| continue; |
| } |
| else { |
| S_do_test_matrix(runner, doc_max, first_doc_id, |
| doc_inc, offset_inc); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| void |
| TestSeriesMatcher_Run_IMP(TestSeriesMatcher *self, TestBatchRunner *runner) { |
| TestBatchRunner_Plan(runner, (TestBatch*)self, 135); |
| test_matrix(runner); |
| } |
| |
| |