Beispiel #1
0
static void
S_grow(Inversion *self, size_t size) {
    InversionIVARS *const ivars = Inversion_IVARS(self);
    if (size > ivars->cap) {
        uint64_t amount = size * sizeof(Token*);
        // Clip rather than wrap.
        if (amount > SIZE_MAX || amount < size) { amount = SIZE_MAX; }
        ivars->tokens = (Token**)REALLOCATE(ivars->tokens, (size_t)amount);
        ivars->cap    = size;
        memset(ivars->tokens + ivars->size, 0,
               (size - ivars->size) * sizeof(Token*));
    }
}
static char*
S_pod_escape(const char *content) {
    size_t  len        = strlen(content);
    size_t  result_len = 0;
    size_t  result_cap = len + 256;
    char   *result     = (char*)MALLOCATE(result_cap + 1);

    for (size_t i = 0; i < len; i++) {
        const char *subst      = content + i;
        size_t      subst_size = 1;

        switch (content[i]) {
            case '<':
                // Escape "less than".
                subst      = "E<lt>";
                subst_size = 5;
                break;
            case '>':
                // Escape "greater than".
                subst      = "E<gt>";
                subst_size = 5;
                break;
            case '|':
                // Escape vertical bar.
                subst      = "E<verbar>";
                subst_size = 9;
                break;
            case '=':
                // Escape equal sign at start of line.
                if (i == 0 || content[i-1] == '\n') {
                    subst      = "E<61>";
                    subst_size = 5;
                }
                break;
            default:
                break;
        }

        if (result_len + subst_size > result_cap) {
            result_cap += 256;
            result = (char*)REALLOCATE(result, result_cap + 1);
        }

        memcpy(result + result_len, subst, subst_size);
        result_len += subst_size;
    }

    result[result_len] = '\0';

    return result;
}
char*
CFCBindMeth_abstract_method_def(CFCMethod *method, CFCClass *klass) {
    CFCType    *ret_type      = CFCMethod_get_return_type(method);
    const char *ret_type_str  = CFCType_to_c(ret_type);
    CFCType    *type          = CFCMethod_self_type(method);
    const char *class_var     = CFCType_get_class_var(type);
    const char *meth_name     = CFCMethod_get_name(method);
    CFCParamList *param_list  = CFCMethod_get_param_list(method);
    const char *params        = CFCParamList_to_c(param_list);
    CFCVariable **vars        = CFCParamList_get_variables(param_list);
    const char *invocant      = CFCVariable_get_name(vars[0]);

    // All variables other than the invocant are unused, and the return is
    // unreachable.
    char *unused = CFCUtil_strdup("");
    for (int i = 1; vars[i] != NULL; i++) {
        const char *var_name = CFCVariable_get_name(vars[i]);
        size_t size = strlen(unused) + strlen(var_name) + 80;
        unused = (char*)REALLOCATE(unused, size);
        strcat(unused, "\n    CFISH_UNUSED_VAR(");
        strcat(unused, var_name);
        strcat(unused, ");");
    }
    char *unreachable;
    if (!CFCType_is_void(ret_type)) {
        unreachable = CFCUtil_sprintf("    CFISH_UNREACHABLE_RETURN(%s);\n",
                                      ret_type_str);
    }
    else {
        unreachable = CFCUtil_strdup("");
    }

    char *full_func_sym = CFCMethod_imp_func(method, klass);

    char pattern[] =
        "%s\n"
        "%s(%s) {\n"
        "%s"
        "    cfish_Err_abstract_method_call((cfish_Obj*)%s, %s, \"%s\");\n"
        "%s"
        "}\n";
    char *abstract_def
        = CFCUtil_sprintf(pattern, ret_type_str, full_func_sym, params,
                          unused, invocant, class_var, meth_name,
                          unreachable);

    FREEMEM(unused);
    FREEMEM(unreachable);
    FREEMEM(full_func_sym);
    return abstract_def;
}
Beispiel #4
0
void
CFCHierarchy_add_include_dir(CFCHierarchy *self, const char *include_dir) {
    // Don't add directory twice.
    for (size_t i = 0; self->includes[i] != NULL; ++i) {
        if (strcmp(self->includes[i], include_dir) == 0) { return; }
    }

    size_t n = self->num_includes;
    size_t size = (n + 2) * sizeof(char*);
    self->includes      = (char**)REALLOCATE(self->includes, size);
    self->includes[n]   = CFCUtil_strdup(include_dir);
    self->includes[n+1] = NULL;
    self->num_includes  = n + 1;
}
void
CFCPerlClass_add_class_alias(CFCPerlClass *self, const char *alias) {
    for (size_t i = 0; i < self->num_class_aliases; i++) {
        if (strcmp(alias, self->class_aliases[i]) == 0) {
            CFCUtil_die("Alias '%s' already added for class '%s'", alias,
                        self->class_name);
        }
    }
    size_t size = (self->num_class_aliases + 2) * sizeof(char*);
    self->class_aliases = (char**)REALLOCATE(self->class_aliases, size);
    self->class_aliases[self->num_class_aliases] = CFCUtil_strdup(alias);
    self->num_class_aliases++;
    self->class_aliases[self->num_class_aliases] = NULL;
}
Beispiel #6
0
static void
S_grow(Inversion *self, size_t size) {
    InversionIVARS *const ivars = Inversion_IVARS(self);
    if (size > ivars->cap) {
        if (size > SIZE_MAX / sizeof(Token*) || size > UINT32_MAX) {
            THROW(ERR, "Can't grow Inversion to hold %u64 elements",
                  (uint64_t)size);
        }
        size_t amount = size * sizeof(Token*);
        ivars->tokens = (Token**)REALLOCATE(ivars->tokens, amount);
        ivars->cap    = (uint32_t)size;
        memset(ivars->tokens + ivars->size, 0,
               (size - ivars->size) * sizeof(Token*));
    }
}
Beispiel #7
0
static char*
S_build_unused_vars(CFCVariable **vars) {
    char *unused = CFCUtil_strdup("");

    for (int i = 0; vars[i] != NULL; i++) {
        const char *var_name = CFCVariable_get_name(vars[i]);
        size_t size = strlen(unused) + strlen(var_name) + 80;
        unused = (char*)REALLOCATE(unused, size);
        strcat(unused, "\n    CFISH_UNUSED_VAR(");
        strcat(unused, var_name);
        strcat(unused, ");");
    }

    return unused;
}
Beispiel #8
0
static char*
S_obj_callback_def(CFCMethod *method, const char *callback_params,
                   const char *refcount_mods) {
    const char *override_sym = CFCMethod_full_override_sym(method);
    const char *params = CFCParamList_to_c(CFCMethod_get_param_list(method));
    CFCType *return_type = CFCMethod_get_return_type(method);
    const char *ret_type_str = CFCType_to_c(return_type);
    const char *cb_func_name = CFCType_is_string_type(return_type)
                               ? "cfish_Host_callback_str"
                               : "cfish_Host_callback_obj";

    char *nullable_check = CFCUtil_strdup("");
    if (!CFCType_nullable(return_type)) {
        const char *macro_sym = CFCMethod_get_macro_sym(method);
        char pattern[] =
            "\n    if (!retval) { CFISH_THROW(CFISH_ERR, "
            "\"%s() for class '%%o' cannot return NULL\", "
            "Cfish_Obj_Get_Class_Name((cfish_Obj*)self)); }";
        size_t size = sizeof(pattern) + strlen(macro_sym) + 30;
        nullable_check = (char*)REALLOCATE(nullable_check, size);
        sprintf(nullable_check, pattern, macro_sym);
    }

    char pattern[] =
        "%s\n"
        "%s(%s) {\n"
        "    %s retval = (%s)%s(%s);%s%s\n"
        "    return retval;\n"
        "}\n";
    size_t size = sizeof(pattern)
                  + strlen(ret_type_str)
                  + strlen(override_sym)
                  + strlen(params)
                  + strlen(ret_type_str)
                  + strlen(ret_type_str)
                  + strlen(cb_func_name)
                  + strlen(callback_params)
                  + strlen(nullable_check)
                  + strlen(refcount_mods)
                  + 30;
    char *callback_def = (char*)MALLOCATE(size);
    sprintf(callback_def, pattern, ret_type_str, override_sym, params,
            ret_type_str, ret_type_str, cb_func_name, callback_params,
            nullable_check, refcount_mods);

    FREEMEM(nullable_check);
    return callback_def;
}
Beispiel #9
0
void
CFCClass_add_method(CFCClass *self, CFCMethod *method) {
    CFCUTIL_NULL_CHECK(method);
    if (self->tree_grown) {
        CFCUtil_die("Can't call add_method after grow_tree");
    }
    if (self->is_inert) {
        CFCUtil_die("Can't add_method to an inert class");
    }
    self->num_methods++;
    size_t size = (self->num_methods + 1) * sizeof(CFCMethod*);
    self->methods = (CFCMethod**)REALLOCATE(self->methods, size);
    self->methods[self->num_methods - 1]
        = (CFCMethod*)CFCBase_incref((CFCBase*)method);
    self->methods[self->num_methods] = NULL;
}
Beispiel #10
0
static void
S_lazy_init_method_bindings(CFCGoClass *self) {
    if (self->method_bindings) {
        return;
    }
    CFCUTIL_NULL_CHECK(self->client);
    size_t        num_bound     = 0;
    CFCMethod   **fresh_methods = CFCClass_fresh_methods(self->client);
    CFCGoMethod **bound
        = (CFCGoMethod**)CALLOCATE(1, sizeof(CFCGoMethod*));

     // Iterate over the class's fresh methods.
    for (size_t i = 0; fresh_methods[i] != NULL; i++) {
        CFCMethod *method = fresh_methods[i];

        // Skip methods which have been explicitly excluded.
        if (CFCMethod_excluded_from_host(method)) {
            continue;
        }

        // Skip methods that shouldn't be bound.
        if (!CFCMethod_can_be_bound(method)) {
            continue;
        }

        // Only include novel methods.
        if (!CFCMethod_novel(method)) {
            continue;
        }
        const char *sym = CFCMethod_get_name(method);
        if (!CFCClass_fresh_method(self->client, sym)) {
            continue;
        }

        /* Create the binding, add it to the array.
         */
        CFCGoMethod *meth_binding = CFCGoMethod_new(method);
        size_t size = (num_bound + 2) * sizeof(CFCGoMethod*);
        bound = (CFCGoMethod**)REALLOCATE(bound, size);
        bound[num_bound] = meth_binding;
        num_bound++;
        bound[num_bound] = NULL;
    }

    self->method_bindings = bound;
    self->num_bound       = num_bound;
}
Beispiel #11
0
static void
S_register(CFCClass *self) {
    if (registry_size == registry_cap) {
        size_t new_cap = registry_cap + 10;
        registry = (CFCClassRegEntry*)REALLOCATE(
                       registry,
                       (new_cap + 1) * sizeof(CFCClassRegEntry));
        for (size_t i = registry_cap; i <= new_cap; i++) {
            registry[i].key = NULL;
            registry[i].klass = NULL;
        }
        registry_cap = new_cap;
    }

    CFCParcel  *parcel     = CFCClass_get_parcel(self);
    const char *prefix     = CFCParcel_get_prefix(parcel);
    const char *class_name = CFCClass_get_class_name(self);
    const char *cnick      = CFCClass_get_cnick(self);
    const char *key        = self->full_struct_sym;

    for (size_t i = 0; i < registry_size; i++) {
        CFCClass   *other            = registry[i].klass;
        CFCParcel  *other_parcel     = CFCClass_get_parcel(other);
        const char *other_prefix     = CFCParcel_get_prefix(other_parcel);
        const char *other_class_name = CFCClass_get_class_name(other);
        const char *other_cnick      = CFCClass_get_cnick(other);

        if (strcmp(class_name, other_class_name) == 0) {
            CFCUtil_die("Two classes with name %s", class_name);
        }
        if (strcmp(registry[i].key, key) == 0) {
            CFCUtil_die("Class name conflict between %s and %s",
                        class_name, other_class_name);
        }
        if (strcmp(prefix, other_prefix) == 0
            && strcmp(cnick, other_cnick) == 0
           ) {
            CFCUtil_die("Class nickname conflict between %s and %s",
                        class_name, other_class_name);
        }
    }

    registry[registry_size].key   = CFCUtil_strdup(key);
    registry[registry_size].klass = (CFCClass*)CFCBase_incref((CFCBase*)self);
    registry_size++;
}
Beispiel #12
0
static void
S_register(CFCDocument *self) {
    if (CFCDocument_fetch(self->name) != NULL) {
        CFCUtil_die("Two documents with name %s", self->name);
    }

    if (registry_size == registry_cap) {
        size_t new_cap = registry_cap + 10;
        size_t bytes   = (new_cap + 1) * sizeof(CFCDocument*);
        registry = (CFCDocument**)REALLOCATE(registry, bytes);
        registry_cap = new_cap;
    }

    registry[registry_size]   = (CFCDocument*)CFCBase_incref((CFCBase*)self);
    registry[registry_size+1] = NULL;
    registry_size++;
}
Beispiel #13
0
static void
S_add_tree(CFCHierarchy *self, CFCClass *klass) {
    CFCUTIL_NULL_CHECK(klass);
    const char *full_struct_sym = CFCClass_full_struct_sym(klass);
    for (size_t i = 0; self->trees[i] != NULL; i++) {
        const char *existing = CFCClass_full_struct_sym(self->trees[i]);
        if (strcmp(full_struct_sym, existing) == 0) {
            CFCUtil_die("Tree '%s' alread added", full_struct_sym);
        }
    }
    self->num_trees++;
    size_t size = (self->num_trees + 1) * sizeof(CFCClass*);
    self->trees = (CFCClass**)REALLOCATE(self->trees, size);
    self->trees[self->num_trees - 1]
        = (CFCClass*)CFCBase_incref((CFCBase*)klass);
    self->trees[self->num_trees] = NULL;
}
Beispiel #14
0
void
CFCParcel_register(CFCParcel *self) {
    CFCParcel *existing = CFCParcel_fetch(self->name);
    if (existing) {
        CFCUtil_die("Parcel '%s' already registered", self->name);
    }
    if (!num_registered) {
        // Init default parcel as first.
        registry = (CFCParcel**)CALLOCATE(3, sizeof(CFCParcel*));
        CFCParcel *def = CFCParcel_default_parcel();
        registry[0] = (CFCParcel*)CFCBase_incref((CFCBase*)def);
        num_registered++;
    }
    size_t size = (num_registered + 2) * sizeof(CFCParcel*);
    registry = (CFCParcel**)REALLOCATE(registry, size);
    registry[num_registered++] = (CFCParcel*)CFCBase_incref((CFCBase*)self);
    registry[num_registered]   = NULL;
}
Beispiel #15
0
static void
S_find_files(const char *path, void *arg) {
    CFCFindFilesContext *context = (CFCFindFilesContext*)arg;
    const char  *ext       = context->ext;
    size_t       path_len  = strlen(path);
    size_t       ext_len   = strlen(ext);

    if (path_len > ext_len && (strcmp(path + path_len - ext_len, ext) == 0)) {
        size_t   num_paths = context->num_paths;
        size_t   size      = (num_paths + 2) * sizeof(char*);
        char   **paths     = (char**)REALLOCATE(context->paths, size);

        paths[num_paths]     = CFCUtil_strdup(path);
        paths[num_paths + 1] = NULL;

        context->num_paths++;
        context->paths = paths;
    }
}
Beispiel #16
0
void
SortEx_Sort_Cache_IMP(SortExternal *self) {
    SortExternalIVARS *const ivars = SortEx_IVARS(self);
    if (ivars->cache_tick != 0) {
        THROW(ERR, "Cant Sort_Cache() after fetching %u32 items", ivars->cache_tick);
    }
    if (ivars->cache_max != 0) {
        VTable *vtable = SortEx_Get_VTable(self);
        CFISH_Sort_Compare_t compare
            = (CFISH_Sort_Compare_t)METHOD_PTR(vtable, LUCY_SortEx_Compare);
        if (ivars->scratch_cap < ivars->cache_cap) {
            ivars->scratch_cap = ivars->cache_cap;
            ivars->scratch
                = (uint8_t*)REALLOCATE(ivars->scratch,
                                       ivars->scratch_cap * ivars->width);
        }
        Sort_mergesort(ivars->cache, ivars->scratch, ivars->cache_max,
                       ivars->width, compare, self);
    }
}
Beispiel #17
0
static void
S_add_file(CFCHierarchy *self, CFCFile *file) {
    CFCUTIL_NULL_CHECK(file);
    CFCClass **classes = CFCFile_classes(file);

    self->num_files++;
    size_t size = (self->num_files + 1) * sizeof(CFCFile*);
    self->files = (CFCFile**)REALLOCATE(self->files, size);
    self->files[self->num_files - 1]
        = (CFCFile*)CFCBase_incref((CFCBase*)file);
    self->files[self->num_files] = NULL;

    for (size_t i = 0; classes[i] != NULL; i++) {
        CFCClass *klass = classes[i];
        const char *parent_name = CFCClass_get_parent_class_name(klass);
        if (!parent_name) {
            S_add_tree(self, klass);
        }
    }
}
Beispiel #18
0
void
CFCGoClass_register(CFCGoClass *self) {
    if (registry_size == registry_cap) {
        size_t new_cap = registry_cap + 10;
        size_t amount = (new_cap + 1) * sizeof(CFCGoClass*);
        registry = (CFCGoClass**)REALLOCATE(registry, amount);
        for (size_t i = registry_cap; i <= new_cap; i++) {
            registry[i] = NULL;
        }
        registry_cap = new_cap;
    }
    CFCGoClass *existing = CFCGoClass_singleton(self->class_name);
    if (existing) {
        CFCUtil_die("Class '%s' already registered", self->class_name);
    }
    registry[registry_size] = (CFCGoClass*)CFCBase_incref((CFCBase*)self);
    registry_size++;
    qsort(registry, registry_size, sizeof(CFCGoClass*),
          S_compare_cfcgoclass);
}
Beispiel #19
0
	/** format **/
	String* String::FormatV(const char* fmt, va_list vl){
		va_list vc;
		va_copy(vc, vl);
		int64_t len =0;
		len =vsnprintf(0, 0, fmt, vl);
		if(len < 0){
			OutputDebug("String::FormatV:vsnprintf fail");
			return 0;
		}
		else if(len == 0){
			return NewString();
		}
		else{
			String* o =NewString();
			o->m_length =len;
			o->m_data =reinterpret_cast< char* >(REALLOCATE(o->m_data, o->m_length + 1));
			vsnprintf(o->m_data, (size_t)(o->m_length+1), fmt, vc);
			return o;
		}
	}
Beispiel #20
0
void
SortEx_Sort_Buffer_IMP(SortExternal *self) {
    SortExternalIVARS *const ivars = SortEx_IVARS(self);
    if (ivars->buf_tick != 0) {
        THROW(ERR, "Cant Sort_Buffer() after fetching %u32 items", ivars->buf_tick);
    }
    if (ivars->buf_max != 0) {
        Class *klass = SortEx_get_class(self);
        CFISH_Sort_Compare_t compare
            = (CFISH_Sort_Compare_t)METHOD_PTR(klass, LUCY_SortEx_Compare);
        if (ivars->scratch_cap < ivars->buf_cap) {
            ivars->scratch_cap = ivars->buf_cap;
            ivars->scratch
                = (Obj**)REALLOCATE(ivars->scratch,
                                    ivars->scratch_cap * sizeof(Obj*));
        }
        Sort_mergesort(ivars->buffer, ivars->scratch, ivars->buf_max,
                       sizeof(Obj*), compare, self);
    }
}
Beispiel #21
0
// Pass down member vars to from parent to children.
static void
S_bequeath_member_vars(CFCClass *self) {
    for (size_t i = 0; self->children[i] != NULL; i++) {
        CFCClass *child = self->children[i];
        size_t num_vars = self->num_member_vars + child->num_member_vars;
        size_t size = (num_vars + 1) * sizeof(CFCVariable*);
        child->member_vars
            = (CFCVariable**)REALLOCATE(child->member_vars, size);
        memmove(child->member_vars + self->num_member_vars,
                child->member_vars,
                child->num_member_vars * sizeof(CFCVariable*));
        memcpy(child->member_vars, self->member_vars,
               self->num_member_vars * sizeof(CFCVariable*));
        for (size_t j = 0; self->member_vars[j] != NULL; j++) {
            CFCBase_incref((CFCBase*)child->member_vars[j]);
        }
        child->num_member_vars = num_vars;
        child->member_vars[num_vars] = NULL;
        S_bequeath_member_vars(child);
    }
}
Beispiel #22
0
void
ScorePost_Read_Record_IMP(ScorePosting *self, InStream *instream) {
    ScorePostingIVARS *const ivars = ScorePost_IVARS(self);
    uint32_t  position = 0;
    const size_t max_start_bytes = (C32_MAX_BYTES * 2) + 1;
    const char *buf = InStream_Buf(instream, max_start_bytes);
    const uint32_t doc_code = NumUtil_decode_c32(&buf);
    const uint32_t doc_delta = doc_code >> 1;

    // Apply delta doc and retrieve freq.
    ivars->doc_id   += doc_delta;
    if (doc_code & 1) {
        ivars->freq = 1;
    }
    else {
        ivars->freq = NumUtil_decode_c32(&buf);
    }

    // Decode boost/norm byte.
    ivars->weight = ivars->norm_decoder[*(uint8_t*)buf];
    buf++;

    // Read positions.
    uint32_t num_prox = ivars->freq;
    if (num_prox > ivars->prox_cap) {
        ivars->prox = (uint32_t*)REALLOCATE(
                         ivars->prox, num_prox * sizeof(uint32_t));
        ivars->prox_cap = num_prox;
    }
    uint32_t *positions = ivars->prox;

    InStream_Advance_Buf(instream, buf);
    buf = InStream_Buf(instream, num_prox * C32_MAX_BYTES);
    while (num_prox--) {
        position += NumUtil_decode_c32(&buf);
        *positions++ = position;
    }

    InStream_Advance_Buf(instream, buf);
}
Beispiel #23
0
void
CFCParcel_register(CFCParcel *self) {
    const char *name     = self->name;
    const char *nickname = self->nickname;

    for (size_t i = 0; i < num_registered ; i++) {
        CFCParcel *other = registry[i];

        if (strcmp(other->name, name) == 0) {
            CFCUtil_die("Parcel '%s' already registered", name);
        }
        if (strcmp(other->nickname, nickname) == 0) {
            CFCUtil_die("Parcel with nickname '%s' already registered",
                        nickname);
        }
    }

    size_t size = (num_registered + 2) * sizeof(CFCParcel*);
    registry = (CFCParcel**)REALLOCATE(registry, size);
    registry[num_registered++] = (CFCParcel*)CFCBase_incref((CFCBase*)self);
    registry[num_registered]   = NULL;
}
Beispiel #24
0
HitDoc*
DefDocReader_Fetch_Doc_IMP(DefaultDocReader *self, int32_t doc_id) {
    DefaultDocReaderIVARS *const ivars = DefDocReader_IVARS(self);
    Schema   *const schema = ivars->schema;
    InStream *const dat_in = ivars->dat_in;
    InStream *const ix_in  = ivars->ix_in;
    Hash     *const fields = Hash_new(1);
    int64_t   start;
    uint32_t  num_fields;
    uint32_t  field_name_cap = 31;
    char     *field_name = (char*)MALLOCATE(field_name_cap + 1);

    // Get data file pointer from index, read number of fields.
    InStream_Seek(ix_in, (int64_t)doc_id * 8);
    start = InStream_Read_U64(ix_in);
    InStream_Seek(dat_in, start);
    num_fields = InStream_Read_C32(dat_in);

    // Decode stored data and build up the doc field by field.
    while (num_fields--) {
        uint32_t        field_name_len;
        Obj       *value;
        FieldType *type;

        // Read field name.
        field_name_len = InStream_Read_C32(dat_in);
        if (field_name_len > field_name_cap) {
            field_name_cap = field_name_len;
            field_name     = (char*)REALLOCATE(field_name,
                                                    field_name_cap + 1);
        }
        InStream_Read_Bytes(dat_in, field_name, field_name_len);

        // Find the Field's FieldType.
        StackString *field_name_str
            = SSTR_WRAP_UTF8(field_name, field_name_len);
        type = Schema_Fetch_Type(schema, (String*)field_name_str);

        // Read the field value.
        switch (FType_Primitive_ID(type) & FType_PRIMITIVE_ID_MASK) {
            case FType_TEXT: {
                    uint32_t value_len = InStream_Read_C32(dat_in);
                    char *buf = (char*)MALLOCATE(value_len + 1);
                    InStream_Read_Bytes(dat_in, buf, value_len);
                    buf[value_len] = '\0'; 
                    value = (Obj*)Str_new_steal_utf8(buf, value_len);
                    break;
                }
            case FType_BLOB: {
                    uint32_t value_len = InStream_Read_C32(dat_in);
                    char *buf = (char*)MALLOCATE(value_len);
                    InStream_Read_Bytes(dat_in, buf, value_len);
                    value = (Obj*)BB_new_steal_bytes(
                                buf, value_len, value_len);
                    break;
                }
            case FType_FLOAT32:
                value = (Obj*)Float32_new(
                                InStream_Read_F32(dat_in));
                break;
            case FType_FLOAT64:
                value = (Obj*)Float64_new(
                                InStream_Read_F64(dat_in));
                break;
            case FType_INT32:
                value = (Obj*)Int32_new(
                                (int32_t)InStream_Read_C32(dat_in));
                break;
            case FType_INT64:
                value = (Obj*)Int64_new(
                                (int64_t)InStream_Read_C64(dat_in));
                break;
            default:
                value = NULL;
                THROW(ERR, "Unrecognized type: %o", type);
        }

        // Store the value.
        Hash_Store_Utf8(fields, field_name, field_name_len, value);
    }
    FREEMEM(field_name);

    HitDoc *retval = HitDoc_new(fields, doc_id, 0.0);
    DECREF(fields);
    return retval;
}
Beispiel #25
0
void addCommand(Command cmd)
{
    commands = (Command*)REALLOCATE(commands, sizeof(Command) * (commandsCount + 1) );
    commands[commandsCount++] = cmd;
    commandNumber++;
}
Beispiel #26
0
static void
S_absorb_slices(SortExternal *self, SortExternalIVARS *ivars,
                Obj **endpost) {
    uint32_t    num_runs     = Vec_Get_Size(ivars->runs);
    Obj      ***slice_starts = ivars->slice_starts;
    uint32_t   *slice_sizes  = ivars->slice_sizes;
    Class      *klass        = SortEx_get_class(self);
    CFISH_Sort_Compare_t compare
        = (CFISH_Sort_Compare_t)METHOD_PTR(klass, LUCY_SortEx_Compare);

    if (ivars->buf_max != 0) { THROW(ERR, "Can't refill unless empty"); }

    // Move all the elements in range into the main buffer as slices.
    for (uint32_t i = 0; i < num_runs; i++) {
        SortExternal *const run = (SortExternal*)Vec_Fetch(ivars->runs, i);
        SortExternalIVARS *const run_ivars = SortEx_IVARS(run);
        uint32_t slice_size = S_find_slice_size(run, run_ivars, endpost);

        if (slice_size) {
            // Move slice content from run buffer to main buffer.
            if (ivars->buf_max + slice_size > ivars->buf_cap) {
                size_t cap = Memory_oversize(ivars->buf_max + slice_size,
                                             sizeof(Obj*));
                SortEx_Grow_Buffer(self, cap);
            }
            memcpy(ivars->buffer + ivars->buf_max,
                   run_ivars->buffer + run_ivars->buf_tick,
                   slice_size * sizeof(Obj*));
            run_ivars->buf_tick += slice_size;
            ivars->buf_max += slice_size;

            // Track number of slices and slice sizes.
            slice_sizes[ivars->num_slices++] = slice_size;
        }
    }

    // Transform slice starts from ticks to pointers.
    uint32_t total = 0;
    for (uint32_t i = 0; i < ivars->num_slices; i++) {
        slice_starts[i] = ivars->buffer + total;
        total += slice_sizes[i];
    }

    // The main buffer now consists of several slices.  Sort the main buffer,
    // but exploit the fact that each slice is already sorted.
    if (ivars->scratch_cap < ivars->buf_cap) {
        ivars->scratch_cap = ivars->buf_cap;
        ivars->scratch = (Obj**)REALLOCATE(
                            ivars->scratch, ivars->scratch_cap * sizeof(Obj*));
    }

    // Exploit previous sorting, rather than sort buffer naively.
    // Leave the first slice intact if the number of slices is odd. */
    while (ivars->num_slices > 1) {
        uint32_t i = 0;
        uint32_t j = 0;

        while (i < ivars->num_slices) {
            if (ivars->num_slices - i >= 2) {
                // Merge two consecutive slices.
                const uint32_t merged_size = slice_sizes[i] + slice_sizes[i + 1];
                Sort_merge(slice_starts[i], slice_sizes[i],
                           slice_starts[i + 1], slice_sizes[i + 1], ivars->scratch,
                           sizeof(Obj*), compare, self);
                slice_sizes[j]  = merged_size;
                slice_starts[j] = slice_starts[i];
                memcpy(slice_starts[j], ivars->scratch, merged_size * sizeof(Obj*));
                i += 2;
                j += 1;
            }
            else if (ivars->num_slices - i >= 1) {
                // Move single slice pointer.
                slice_sizes[j]  = slice_sizes[i];
                slice_starts[j] = slice_starts[i];
                i += 1;
                j += 1;
            }
        }
        ivars->num_slices = j;
    }

    ivars->num_slices = 0;
}