예제 #1
0
파일: TestObj.c 프로젝트: pavansondur/lucy
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);
}
예제 #2
0
파일: Hash.c 프로젝트: pavansondur/lucy
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;
}
예제 #3
0
파일: Hash.c 프로젝트: hernan604/lucy
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
    }
}
예제 #4
0
파일: RangeQuery.c 프로젝트: apache/lucy
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;
}
예제 #5
0
파일: RangeQuery.c 프로젝트: apache/lucy
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;
}
예제 #6
0
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;
}
예제 #7
0
파일: TestJson.c 프로젝트: rectang/lucy
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);
}
예제 #8
0
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);
}
예제 #9
0
파일: TestHash.c 프로젝트: pavansondur/lucy
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);
}
예제 #10
0
파일: TestJson.c 프로젝트: pavansondur/lucy
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);
}
예제 #11
0
파일: TermQuery.c 프로젝트: apache/lucy
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;
}
예제 #12
0
파일: TestObj.c 프로젝트: pavansondur/lucy
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);
}
예제 #13
0
파일: RangeQuery.c 프로젝트: apache/lucy
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;
}
예제 #14
0
파일: Schema.c 프로젝트: lazycrazyowl/lucy
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));
}
예제 #15
0
파일: TestJson.c 프로젝트: pavansondur/lucy
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);
}
예제 #16
0
파일: Schema.c 프로젝트: lazycrazyowl/lucy
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);
}
예제 #17
0
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;
}
예제 #18
0
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;
}
예제 #19
0
파일: Hash.c 프로젝트: hernan604/lucy
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++;
    }
}
예제 #20
0
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;
}