static void test_Equals(TestBatch *batch) { Obj *testobj = S_new_testobj(); Obj *other = S_new_testobj(); TEST_TRUE(batch, Obj_Equals(testobj, testobj), "Equals is true for the same object"); TEST_FALSE(batch, Obj_Equals(testobj, other), "Distinct objects are not equal"); DECREF(testobj); DECREF(other); }
bool_t Hash_equals(Hash *self, Obj *other) { Hash *twin = (Hash*)other; Obj *key; Obj *val; if (twin == self) { return true; } if (!Obj_Is_A(other, HASH)) { return false; } if (self->size != twin->size) { return false; } Hash_Iterate(self); while (Hash_Next(self, &key, &val)) { Obj *other_val = Hash_Fetch(twin, key); if (!other_val || !Obj_Equals(other_val, val)) { return false; } } return true; }
void Hash_do_store(Hash *self, Obj *key, Obj *value, int32_t hash_sum, bool use_this_key) { HashEntry *entries = self->size >= self->threshold ? SI_rebuild_hash(self) : (HashEntry*)self->entries; uint32_t tick = hash_sum; const uint32_t mask = self->capacity - 1; while (1) { tick &= mask; HashEntry *entry = entries + tick; if (entry->key == (Obj*)TOMBSTONE || !entry->key) { if (entry->key == (Obj*)TOMBSTONE) { // Take note of diminished tombstone clutter. self->threshold++; } entry->key = use_this_key ? key : Hash_Make_Key(self, key, hash_sum); entry->value = value; entry->hash_sum = hash_sum; self->size++; break; } else if (entry->hash_sum == hash_sum && Obj_Equals(key, entry->key) ) { DECREF(entry->value); entry->value = value; break; } tick++; // linear scan } }
static int32_t S_find_lower_bound(RangeCompiler *self, SortCache *sort_cache) { RangeQuery *parent = (RangeQuery*)RangeCompiler_IVARS(self)->parent; Obj *lower_term = RangeQuery_IVARS(parent)->lower_term; int32_t lower_bound = 0; if (lower_term) { int32_t low_ord = SortCache_Find(sort_cache, lower_term); if (low_ord < 0) { // The supplied term is lower than all terms in the field. lower_bound = 0; } else { Obj *low_found = SortCache_Value(sort_cache, low_ord); bool exact_match = low_found == NULL ? false : Obj_Equals(lower_term, low_found); lower_bound = low_ord; if (!exact_match || !RangeQuery_IVARS(parent)->include_lower) { lower_bound++; } DECREF(low_found); } } return lower_bound; }
static int32_t S_find_upper_bound(RangeCompiler *self, SortCache *sort_cache) { RangeQuery *parent = (RangeQuery*)RangeCompiler_IVARS(self)->parent; Obj *upper_term = RangeQuery_IVARS(parent)->upper_term; int32_t retval = INT32_MAX; if (upper_term) { int32_t hi_ord = SortCache_Find(sort_cache, upper_term); if (hi_ord < 0) { // The supplied term is lower than all terms in the field. retval = -1; } else { Obj *hi_found = SortCache_Value(sort_cache, hi_ord); bool exact_match = hi_found == NULL ? false : Obj_Equals(upper_term, (Obj*)hi_found); retval = hi_ord; if (exact_match && !RangeQuery_IVARS(parent)->include_upper) { retval--; } DECREF(hi_found); } } return retval; }
bool_t RangeQuery_equals(RangeQuery *self, Obj *other) { RangeQuery *twin = (RangeQuery*)other; if (twin == self) { return true; } if (!Obj_Is_A(other, RANGEQUERY)) { return false; } if (self->boost != twin->boost) { return false; } if (!CB_Equals(self->field, (Obj*)twin->field)) { return false; } if (self->lower_term && !twin->lower_term) { return false; } if (self->upper_term && !twin->upper_term) { return false; } if (!self->lower_term && twin->lower_term) { return false; } if (!self->upper_term && twin->upper_term) { return false; } if (self->lower_term && !Obj_Equals(self->lower_term, twin->lower_term)) { return false; } if (self->upper_term && !Obj_Equals(self->upper_term, twin->upper_term)) { return false; } if (self->include_lower != twin->include_lower) { return false; } if (self->include_upper != twin->include_upper) { return false; } return true; }
static void test_to_and_from(TestBatchRunner *runner) { Obj *dump = S_make_dump(); String *json = Json_to_json(dump); Obj *got = Json_from_json(json); TEST_TRUE(runner, got != NULL && Obj_Equals(dump, got), "Round trip through to_json and from_json"); DECREF(dump); DECREF(json); DECREF(got); }
static void test_Dump_Load_and_Equals(TestBatch *batch) { CaseFolder *case_folder = CaseFolder_new(); CaseFolder *other = CaseFolder_new(); Obj *dump = Obj_Dump(case_folder); CaseFolder *clone = (CaseFolder*)Obj_Load(other, dump); ASSERT_TRUE(batch, Obj_Equals(case_folder, (Obj*)other), "Equals"); ASSERT_TRUE(batch, CaseFolder_Dump_Equals(case_folder, (Obj*)dump), "Dump_Equals"); ASSERT_FALSE(batch, Obj_Equals(case_folder, (Obj*)&EMPTY), "Not Equals"); ASSERT_TRUE(batch, Obj_Equals(case_folder, (Obj*)clone), "Dump => Load round trip"); DECREF(case_folder); DECREF(other); DECREF(dump); DECREF(clone); }
static void test_Keys_Values_Iter(TestBatch *batch) { Hash *hash = Hash_new(0); // trigger multiple rebuilds. VArray *expected = VA_new(100); VArray *keys; VArray *values; for (uint32_t i = 0; i < 500; i++) { CharBuf *cb = CB_newf("%u32", i); Hash_Store(hash, (Obj*)cb, (Obj*)cb); VA_Push(expected, INCREF(cb)); } VA_Sort(expected, NULL, NULL); keys = Hash_Keys(hash); values = Hash_Values(hash); VA_Sort(keys, NULL, NULL); VA_Sort(values, NULL, NULL); TEST_TRUE(batch, VA_Equals(keys, (Obj*)expected), "Keys"); TEST_TRUE(batch, VA_Equals(values, (Obj*)expected), "Values"); VA_Clear(keys); VA_Clear(values); { Obj *key; Obj *value; Hash_Iterate(hash); while (Hash_Next(hash, &key, &value)) { VA_Push(keys, INCREF(key)); VA_Push(values, INCREF(value)); } } VA_Sort(keys, NULL, NULL); VA_Sort(values, NULL, NULL); TEST_TRUE(batch, VA_Equals(keys, (Obj*)expected), "Keys from Iter"); TEST_TRUE(batch, VA_Equals(values, (Obj*)expected), "Values from Iter"); { ZombieCharBuf *forty = ZCB_WRAP_STR("40", 2); ZombieCharBuf *nope = ZCB_WRAP_STR("nope", 4); Obj *key = Hash_Find_Key(hash, (Obj*)forty, ZCB_Hash_Sum(forty)); TEST_TRUE(batch, Obj_Equals(key, (Obj*)forty), "Find_Key"); key = Hash_Find_Key(hash, (Obj*)nope, ZCB_Hash_Sum(nope)), TEST_TRUE(batch, key == NULL, "Find_Key returns NULL for non-existent key"); } DECREF(hash); DECREF(expected); DECREF(keys); DECREF(values); }
static void test_to_and_from(TestBatch *batch) { Obj *dump = S_make_dump(); CharBuf *json = Json_to_json(dump); Obj *got = Json_from_json(json); TEST_TRUE(batch, got != NULL && Obj_Equals(dump, got), "Round trip through to_json and from_json"); DECREF(dump); DECREF(json); DECREF(got); }
bool TermQuery_Equals_IMP(TermQuery *self, Obj *other) { if ((TermQuery*)other == self) { return true; } if (!Obj_is_a(other, TERMQUERY)) { return false; } TermQueryIVARS *const ivars = TermQuery_IVARS(self); TermQueryIVARS *const ovars = TermQuery_IVARS((TermQuery*)other); if (ivars->boost != ovars->boost) { return false; } if (!Str_Equals(ivars->field, (Obj*)ovars->field)) { return false; } if (!Obj_Equals(ivars->term, ovars->term)) { return false; } return true; }
static void test_Dump(TestBatch *batch) { Obj *testobj = S_new_testobj(); CharBuf *string = Obj_To_String(testobj); Obj *dump = Obj_Dump(testobj); TEST_TRUE(batch, Obj_Equals(dump, (Obj*)string), "Default Dump returns To_String"); DECREF(dump); DECREF(string); DECREF(testobj); }
bool RangeQuery_Equals_IMP(RangeQuery *self, Obj *other) { if ((RangeQuery*)other == self) { return true; } if (!Obj_is_a(other, RANGEQUERY)) { return false; } RangeQueryIVARS *const ivars = RangeQuery_IVARS(self); RangeQueryIVARS *const ovars = RangeQuery_IVARS((RangeQuery*)other); if (ivars->boost != ovars->boost) { return false; } if (!Str_Equals(ivars->field, (Obj*)ovars->field)) { return false; } if (ivars->lower_term && !ovars->lower_term) { return false; } if (ivars->upper_term && !ovars->upper_term) { return false; } if (!ivars->lower_term && ovars->lower_term) { return false; } if (!ivars->upper_term && ovars->upper_term) { return false; } if (ivars->lower_term && !Obj_Equals(ivars->lower_term, ovars->lower_term)) { return false; } if (ivars->upper_term && !Obj_Equals(ivars->upper_term, ovars->upper_term)) { return false; } if (ivars->include_lower != ovars->include_lower) { return false; } if (ivars->include_upper != ovars->include_upper) { return false; } return true; }
static void S_add_unique(Vector *array, Obj *elem) { if (!elem) { return; } for (uint32_t i = 0, max = Vec_Get_Size(array); i < max; i++) { Obj *candidate = Vec_Fetch(array, i); if (!candidate) { continue; } if (elem == candidate) { return; } if (Obj_get_class(elem) == Obj_get_class(candidate)) { if (Obj_Equals(elem, candidate)) { return; } } } Vec_Push(array, INCREF(elem)); }
static void test_spew_and_slurp(TestBatch *batch) { Obj *dump = S_make_dump(); Folder *folder = (Folder*)RAMFolder_new(NULL); CharBuf *foo = (CharBuf*)ZCB_WRAP_STR("foo", 3); bool_t result = Json_spew_json(dump, folder, foo); TEST_TRUE(batch, result, "spew_json returns true on success"); TEST_TRUE(batch, Folder_Exists(folder, foo), "spew_json wrote file"); Obj *got = Json_slurp_json(folder, foo); TEST_TRUE(batch, got && Obj_Equals(dump, got), "Round trip through spew_json and slurp_json"); DECREF(got); Err_set_error(NULL); result = Json_spew_json(dump, folder, foo); TEST_FALSE(batch, result, "Can't spew_json when file exists"); TEST_TRUE(batch, Err_get_error() != NULL, "Failed spew_json sets Err_error"); Err_set_error(NULL); CharBuf *bar = (CharBuf*)ZCB_WRAP_STR("bar", 3); got = Json_slurp_json(folder, bar); TEST_TRUE(batch, got == NULL, "slurp_json returns NULL when file doesn't exist"); TEST_TRUE(batch, Err_get_error() != NULL, "Failed slurp_json sets Err_error"); CharBuf *boffo = (CharBuf*)ZCB_WRAP_STR("boffo", 5); FileHandle *fh = Folder_Open_FileHandle(folder, boffo, FH_CREATE | FH_WRITE_ONLY); FH_Write(fh, "garbage", 7); DECREF(fh); Err_set_error(NULL); got = Json_slurp_json(folder, boffo); TEST_TRUE(batch, got == NULL, "slurp_json returns NULL when file doesn't contain valid JSON"); TEST_TRUE(batch, Err_get_error() != NULL, "Failed slurp_json sets Err_error"); DECREF(got); DECREF(dump); DECREF(folder); }
uint32_t S_find_in_array(Vector *array, Obj *obj) { for (uint32_t i = 0, max = Vec_Get_Size(array); i < max; i++) { Obj *candidate = Vec_Fetch(array, i); if (obj == NULL && candidate == NULL) { return i; } else if (obj != NULL && candidate != NULL) { if (Obj_get_class(obj) == Obj_get_class(candidate)) { if (Obj_Equals(obj, candidate)) { return i; } } } } THROW(ERR, "Couldn't find match for %o", obj); UNREACHABLE_RETURN(uint32_t); }
bool VA_Equals_IMP(VArray *self, Obj *other) { VArray *twin = (VArray*)other; if (twin == self) { return true; } if (!Obj_Is_A(other, VARRAY)) { return false; } if (twin->size != self->size) { return false; } else { for (uint32_t i = 0, max = self->size; i < max; i++) { Obj *val = self->elems[i]; Obj *other_val = twin->elems[i]; if ((val && !other_val) || (other_val && !val)) { return false; } if (val && !Obj_Equals(val, other_val)) { return false; } } } return true; }
static TermInfo* S_find_tinfo(DefaultLexiconReader *self, String *field, Obj *target) { DefaultLexiconReaderIVARS *const ivars = DefLexReader_IVARS(self); if (field != NULL && target != NULL) { int32_t field_num = Seg_Field_Num(ivars->segment, field); SegLexicon *lexicon = (SegLexicon*)VA_Fetch(ivars->lexicons, field_num); if (lexicon) { // Iterate until the result is ge the term. SegLex_Seek(lexicon, target); //if found matches target, return info; otherwise NULL Obj *found = SegLex_Get_Term(lexicon); if (found && Obj_Equals(target, found)) { return SegLex_Get_Term_Info(lexicon); } } } return NULL; }
static CFISH_INLINE HashEntry* SI_fetch_entry(Hash *self, Obj *key, int32_t hash_sum) { uint32_t tick = hash_sum; HashEntry *const entries = (HashEntry*)self->entries; HashEntry *entry; while (1) { tick &= self->capacity - 1; entry = entries + tick; if (!entry->key) { // Failed to find the key, so return NULL. return NULL; } else if (entry->hash_sum == hash_sum && Obj_Equals(key, entry->key) ) { return entry; } tick++; } }
TermInfo* DefLexReader_fetch_term_info(DefaultLexiconReader *self, const CharBuf *field, Obj *target) { if (field != NULL && target != NULL) { i32_t field_num = Seg_Field_Num(self->segment, field); SegLexicon *lexicon = (SegLexicon*)VA_Fetch(self->lexicons, field_num); if (lexicon) { /* Iterate until the result is ge the term. */ SegLex_Seek(lexicon, target); /*if found matches target, return info; otherwise NULL */ { Obj *found = SegLex_Get_Term(lexicon); if (found && Obj_Equals(target, found)) { return SegLex_Get_Term_Info(lexicon); } } } } return NULL; }