Пример #1
0
int ctable_factory_base::setup(int dfd, const char * name, const params & config, dtype::ctype key_type)
{
	istr base;
	params base_config;
	if(!config.get("base", &base) || !config.get("base_config", &base_config))
		return NULL;
	return setup(base, dfd, name, base_config, key_type);
}
Пример #2
0
int exist_dtable::create(int dfd, const char * file, const params & config, dtable::iter * source, const ktable * shadow)
{
	int e_dfd, r;
	params base_config, dnebase_config;
	const dtable_factory * base = dtable_factory::lookup(config, "base");
	const dtable_factory * dnebase = dtable_factory::lookup(config, "dnebase");
	if(!base || !dnebase)
		return -ENOENT;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	if(!config.get("dnebase_config", &dnebase_config, params()))
		return -EINVAL;
	
	if(!source_shadow_ok(source, shadow))
		return -EINVAL;
	
	r = mkdirat(dfd, file, 0755);
	if(r < 0)
		return r;
	e_dfd = openat(dfd, file, O_RDONLY);
	if(e_dfd < 0)
		goto fail_open;
	
	/* just to be sure */
	source->first();
	{
		dtable_skip_iter<dne_skip_test> base_source(source);
		r = base->create(e_dfd, "base", base_config, &base_source, NULL);
		if(r < 0)
			goto fail_base;
	}
	
	source->first();
	{
		full_ktable full_shadow(source);
		nonshadow_skip_test skip_test(shadow);
		dtable_skip_iter<nonshadow_skip_test> dnebase_source(source, skip_test);
		r = dnebase->create(e_dfd, "dnebase", dnebase_config, &dnebase_source, &full_shadow);
		if(r < 0)
			goto fail_dnebase;
	}
	
	close(e_dfd);
	return 0;
	
fail_dnebase:
	util::rm_r(e_dfd, "base");
fail_base:
	close(e_dfd);
fail_open:
	unlinkat(dfd, file, AT_REMOVEDIR);
	return (r < 0) ? r : -1;
}
Пример #3
0
int deltaint_dtable::init(int dfd, const char * file, const params & config, sys_journal * sysj)
{
	const dtable_factory * base_factory;
	const dtable_factory * ref_factory;
	params base_config, ref_config;
	int di_dfd;
	if(base)
		deinit();
	base_factory = dtable_factory::lookup(config, "base");
	ref_factory = dtable_factory::lookup(config, "ref");
	if(!base_factory || !ref_factory)
		return -ENOENT;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	if(!config.get("ref_config", &ref_config, params()))
		return -EINVAL;
	di_dfd = openat(dfd, file, O_RDONLY);
	if(di_dfd < 0)
		return di_dfd;
	base = base_factory->open(di_dfd, "base", base_config, sysj);
	if(!base)
		goto fail_base;
	reference = ref_factory->open(di_dfd, "ref", ref_config, sysj);
	if(!reference)
		goto fail_reference;
	ktype = base->key_type();
	cmp_name = base->get_cmp_name();
	
	assert(ktype == reference->key_type());
	
	scan_iter = base->iterator();
	if(!scan_iter)
		goto fail_scan;
	ref_iter = reference->iterator();
	if(!ref_iter)
		goto fail_iter;
	
	close(di_dfd);
	return 0;
	
fail_iter:
	delete scan_iter;
	scan_iter = NULL;
fail_scan:
	reference->destroy();
	reference = NULL;
fail_reference:
	base->destroy();
	base = NULL;
fail_base:
	close(di_dfd);
	return -1;
}
Пример #4
0
 amg(
         const Matrix &A,
         const params &prm = params(),
         const backend_params &backend_prm = backend_params()
    )
   : coarsening(prm.get("coarsening.type", runtime::coarsening::smoothed_aggregation)),
     relaxation(prm.get("relaxation.type", runtime::relaxation::spai0)),
     handle(0)
 {
     runtime::detail::process_amg<Backend>(
             coarsening, relaxation,
             runtime::detail::amg_create<Backend, Matrix>(handle, A, prm, backend_prm)
             );
 }
Пример #5
0
int exception_dtable::init(int dfd, const char * file, const params & config, sys_journal * sysj)
{
	const dtable_factory * base_factory;
	const dtable_factory * alt_factory;
	params base_config, alt_config;
	int excp_dfd;
	if(base || alt)
		deinit();
	base_factory = dtable_factory::lookup(config, "base");
	alt_factory = dtable_factory::lookup(config, "alt");
	if(!base_factory || !alt_factory)
		return -EINVAL;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	if(!config.get("alt_config", &alt_config, params()))
		return -EINVAL;
	if(!config.get_blob_or_string("reject_value", &reject_value))
		return -EINVAL;
	/* the reject value must exist, because nonexistent values
	 * can get pruned out if the shadow does not require them */
	if(!reject_value.exists())
		return -EINVAL;
	excp_dfd = openat(dfd, file, O_RDONLY);
	if(excp_dfd < 0)
		return excp_dfd;
	base = base_factory->open(excp_dfd, "base", base_config, sysj);
	if(!base)
		goto fail_base;
	alt = alt_factory->open(excp_dfd, "alt", alt_config, sysj);
	if(!alt)
		goto fail_alt;
	ktype = base->key_type();
	if(ktype != alt->key_type())
		goto fail_ktype;
	cmp_name = base->get_cmp_name();
	
	close(excp_dfd);
	return 0;
	
fail_ktype:
	alt->destroy();
	alt = NULL;
fail_alt:
	base->destroy();
	base = NULL;
fail_base:
	close(excp_dfd);
	return -1;
}
Пример #6
0
    wrapper(size_t n, params prm = params(),
            const backend_params &bprm = backend_params(),
            const InnerProduct &inner_product = InnerProduct()
            )
        : s(prm.get("type", runtime::solver::bicgstab)), handle(0)
    {
        if (!prm.erase("type")) AMGCL_PARAM_MISSING("type");

        switch(s) {

#define AMGCL_RUNTIME_SOLVER(type) \
            case type: \
                handle = static_cast<void*>(new amgcl::solver::type<Backend, InnerProduct>(n, prm, bprm, inner_product)); \
                break

            AMGCL_RUNTIME_SOLVER(cg);
            AMGCL_RUNTIME_SOLVER(bicgstab);
            AMGCL_RUNTIME_SOLVER(bicgstabl);
            AMGCL_RUNTIME_SOLVER(gmres);
            AMGCL_RUNTIME_SOLVER(lgmres);
            AMGCL_RUNTIME_SOLVER(fgmres);
            AMGCL_RUNTIME_SOLVER(idrs);

#undef AMGCL_RUNTIME_SOLVER

            default:
                throw std::invalid_argument("Unsupported solver type");
        }
    }
Пример #7
0
int btree_dtable::init(int dfd, const char * file, const params & config, sys_journal * sysj)
{
	const dtable_factory * factory;
	params base_config;
	int r, bt_dfd;
	if(base)
		deinit();
	factory = dtable_factory::lookup(config, "base");
	if(!factory)
		return -ENOENT;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	if(!factory->indexed_access(base_config))
		return -ENOSYS;
	bt_dfd = openat(dfd, file, O_RDONLY);
	if(bt_dfd < 0)
		return bt_dfd;
	base = factory->open(bt_dfd, "base", base_config, sysj);
	if(!base)
		goto fail_base;
	ktype = base->key_type();
	assert(ktype == dtype::UINT32);
	cmp_name = base->get_cmp_name();
	
	/* open the btree */
	btree = rofile::open<BTREE_PAGE_KB, 8>(bt_dfd, "btree");
	if(!btree)
		goto fail_open;
	r = btree->read_type(0, &header);
	if(r < 0)
		goto fail_format;
	/* check the header */
	if(header.magic != BTREE_DTABLE_MAGIC || header.version != BTREE_DTABLE_VERSION)
		goto fail_format;
	if(header.page_size != BTREE_PAGE_SIZE || header.pageno_size != BTREE_PAGENO_SIZE)
		goto fail_format;
	if(header.key_size != BTREE_KEY_SIZE || header.index_size != BTREE_INDEX_SIZE)
		goto fail_format;
	/* 1 -> uint32, and even with an empty table there will be a root page */
	if(header.key_type != 1 || !header.root_page)
		goto fail_format;
	
	close(bt_dfd);
	return 0;
	
fail_format:
	delete btree;
fail_open:
	base->destroy();
	base = NULL;
fail_base:
	close(bt_dfd);
	return -1;
}
Пример #8
0
int simple_stable::create(int dfd, const char * name, const params & config, dtype::ctype key_type)
{
	int md_dfd, r;
	params meta_config, data_config;
	const dtable_factory * meta = dtable_factory::lookup(config, "meta");
	const ctable_factory * data = ctable_factory::lookup(config, "data");
	if(!meta || !data)
		return -ENOENT;
	if(!config.get("meta_config", &meta_config, params()))
		return -EINVAL;
	if(!config.get("data_config", &data_config, params()))
		return -EINVAL;
	r = mkdirat(dfd, name, 0755);
	if(r < 0)
		return r;
	md_dfd = openat(dfd, name, O_RDONLY);
	if(md_dfd < 0)
	{
		r = md_dfd;
		goto fail_open;
	}
	
	/* the metadata is keyed by named properties (strings) */
	r = meta->create(md_dfd, "st_meta", meta_config, dtype::STRING);
	if(r < 0)
		goto fail_meta;
	r = data->create(md_dfd, "st_data", data_config, key_type);
	if(r < 0)
		goto fail_data;
	
	close(md_dfd);
	return 0;
	
fail_data:
	util::rm_r(md_dfd, "st_meta");
fail_meta:
	close(md_dfd);
fail_open:
	unlinkat(dfd, name, AT_REMOVEDIR);
	return r;
}
Пример #9
0
int simple_stable::init(int dfd, const char * name, const params & config, sys_journal * sysj)
{
	int r = -1;
	params meta_config, data_config;
	const dtable_factory * meta = dtable_factory::lookup(config, "meta");
	const ctable_factory * data = ctable_factory::lookup(config, "data");
	if(md_dfd >= 0)
		deinit();
	assert(column_map.empty());
	if(!meta || !data)
		return -ENOENT;
	if(!config.get("meta_config", &meta_config, params()))
		return -EINVAL;
	if(!config.get("data_config", &data_config, params()))
		return -EINVAL;
	md_dfd = openat(dfd, name, O_RDONLY);
	if(md_dfd < 0)
		return md_dfd;
	dt_meta = meta->open(md_dfd, "st_meta", meta_config, sysj);
	if(!dt_meta)
		goto fail_meta;
	ct_data = data->open(md_dfd, "st_data", data_config, sysj);
	if(!ct_data)
		goto fail_data;
	
	/* check sanity? */
	r = load_columns();
	if(r < 0)
		goto fail_check;
	
	return 0;
	
fail_check:
	delete ct_data;
fail_data:
	dt_meta->destroy();
fail_meta:
	close(md_dfd);
	md_dfd = -1;
	return r;
}
Пример #10
0
        preconditioner(
                const Matrix &A,
                params prm = params(),
                const backend_params &bprm = backend_params())
            : _class(prm.get("class", runtime::precond_class::amg)),
              handle(0)
        {
            if (!prm.erase("class")) AMGCL_PARAM_MISSING("class");

            switch(_class) {
                case precond_class::amg:
                    {
                        typedef
                            runtime::amg<Backend>
                            Precond;

                        handle = static_cast<void*>(new Precond(A, prm, bprm));
                    }
                    break;
                case precond_class::relaxation:
                    {
                        typedef
                            runtime::relaxation::as_preconditioner<Backend>
                            Precond;

                        handle = static_cast<void*>(new Precond(A, prm, bprm));
                    }
                    break;
                case precond_class::dummy:
                    {
                        typedef
                            amgcl::preconditioner::dummy<Backend>
                            Precond;

                        handle = static_cast<void*>(new Precond(A, prm, bprm));
                    }
                    break;
                case precond_class::nested:
                    {
                        typedef
                            make_solver<
                                preconditioner,
                                runtime::iterative_solver<Backend>
                                >
                            Precond;

                        handle = static_cast<void*>(new Precond(A, prm, bprm));
                    }
                    break;
                default:
                    throw std::invalid_argument("Unsupported preconditioner class");
            }
        }
Пример #11
0
int cache_dtable::init(int dfd, const char * file, const params & config, sys_journal * sysj)
{
	int r;
	const dtable_factory * factory;
	params base_config;
	if(base)
		deinit();
	if(!config.get("cache_size", &r, 0) || r < 0)
		return -EINVAL;
	cache_size = r;
	factory = dtable_factory::lookup(config, "base");
	if(!factory)
		return -EINVAL;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	base = factory->open(dfd, file, base_config, sysj);
	if(!base)
		return -1;
	ktype = base->key_type();
	cmp_name = base->get_cmp_name();
	return 0;
}
Пример #12
0
int btree_dtable::create(int dfd, const char * file, const params & config, dtable::iter * source, const ktable * shadow)
{
	int bt_dfd, r;
	params base_config;
	dtable * base_dtable;
	const dtable_factory * base = dtable_factory::lookup(config, "base");
	if(!base)
		return -ENOENT;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	if(!base->indexed_access(base_config))
		return -ENOSYS;
	
	if(!source_shadow_ok(source, shadow))
		return -EINVAL;
	
	r = mkdirat(dfd, file, 0755);
	if(r < 0)
		return r;
	bt_dfd = openat(dfd, file, O_RDONLY);
	if(bt_dfd < 0)
		goto fail_open;
	
	r = base->create(bt_dfd, "base", base_config, source, shadow);
	if(r < 0)
		goto fail_create;
	
	base_dtable = base->open(bt_dfd, "base", base_config, NULL);
	if(!base_dtable)
		goto fail_reopen;
	
	r = write_btree(bt_dfd, "btree", base_dtable);
	if(r < 0)
		goto fail_write;
	
	base_dtable->destroy();
	
	close(bt_dfd);
	return 0;
	
fail_write:
	base_dtable->destroy();
fail_reopen:
	util::rm_r(bt_dfd, "base");
fail_create:
	close(bt_dfd);
fail_open:
	unlinkat(dfd, file, AT_REMOVEDIR);
	return (r < 0) ? r : -1;
}
Пример #13
0
    wrapper(const amgcl::mpi::distributed_matrix<Backend> &A,
            params prm, const backend_params &bprm = backend_params())
      : r(prm.get("type", runtime::relaxation::spai0)), handle(0)
    {
        if (!prm.erase("type")) AMGCL_PARAM_MISSING("type");

        switch(r) {

#define AMGCL_RELAX_DISTR(type) \
            case runtime::relaxation::type: \
                handle = static_cast<void*>(new amgcl::mpi::relaxation::type<Backend>(A, prm, bprm)); \
                break

#define AMGCL_RELAX_LOCAL_DISTR(type) \
            case runtime::relaxation::type: \
                handle = call_constructor<amgcl::relaxation::type>(A, prm, bprm); \
                break;

#define AMGCL_RELAX_LOCAL_LOCAL(type) \
            case runtime::relaxation::type: \
                handle = call_constructor<amgcl::relaxation::type>(*A.local(), prm, bprm); \
                break;

            AMGCL_RELAX_DISTR(spai0);
            AMGCL_RELAX_LOCAL_DISTR(chebyshev);
            AMGCL_RELAX_LOCAL_LOCAL(damped_jacobi);
            AMGCL_RELAX_LOCAL_LOCAL(ilu0);
            AMGCL_RELAX_LOCAL_LOCAL(iluk);
            AMGCL_RELAX_LOCAL_LOCAL(ilut);
            AMGCL_RELAX_LOCAL_LOCAL(spai1);
            AMGCL_RELAX_LOCAL_LOCAL(gauss_seidel);

#undef AMGCL_RELAX_LOCAL_LOCAL
#undef AMGCL_RELAX_LOCAL_DISTR
#undef AMGCL_RELAX_DISTR

            default:
                throw std::invalid_argument("Unsupported relaxation type");
        }
    }
Пример #14
0
int simple_ctable::create(int dfd, const char * file, const params & config, dtype::ctype key_type)
{
	int ct_dfd, columns, r;
	params base_config;
	std::set<istr, strcmp_less> names;
	
	ctable_header meta;
	rwfile meta_file;
	
	const dtable_factory * base = dtable_factory::lookup(config, "base");
	if(!base)
		return -ENOENT;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	
	if(!config.get("columns", &columns, 0))
		return -EINVAL;
	if(columns < 1)
		return -EINVAL;
	
	/* check that we have all the names */
	for(int i = 0; i < columns; i++)
	{
		char string[32];
		istr column_name;
		sprintf(string, "column%d_name", i);
		if(!config.get(string, &column_name) || !column_name)
			return -EINVAL;
		if(names.count(column_name))
			return -EEXIST;
		names.insert(column_name);
	}
	names.clear();
	
	r = mkdirat(dfd, file, 0755);
	if(r < 0)
		return r;
	ct_dfd = openat(dfd, file, O_RDONLY);
	if(ct_dfd < 0)
		goto fail_open;
	
	meta.magic = SIMPLE_CTABLE_MAGIC;
	meta.version = SIMPLE_CTABLE_VERSION;
	meta.columns = columns;
	r = meta_file.create(ct_dfd, "sct_meta");
	if(r < 0)
		goto fail_meta;
	r = meta_file.append(&meta);
	if(r < 0)
		goto fail_create;
	
	/* record column names */
	for(int i = 0; i < columns; i++)
	{
		uint32_t length;
		char string[32];
		istr column_name;
		sprintf(string, "column%d_name", i);
		r = config.get(string, &column_name);
		assert(r && column_name);
		length = column_name.length();
		r = meta_file.append(&length);
		if(r < 0)
			goto fail_create;
		r = meta_file.append(column_name);
		if(r < 0)
			goto fail_create;
	}
	
	r = base->create(ct_dfd, "base", base_config, key_type);
	if(r < 0)
		goto fail_create;
	
	meta_file.close();
	close(ct_dfd);
	return 0;
	
fail_create:
	meta_file.close();
	unlinkat(dfd, "sct_meta", 0);
fail_meta:
	close(ct_dfd);
fail_open:
	unlinkat(dfd, file, AT_REMOVEDIR);
	return -1;
}
Пример #15
0
int simple_ctable::init(int dfd, const char * file, const params & config, sys_journal * sysj)
{
	const dtable_factory * factory;
	params base_config;
	int ct_dfd, r;
	
	off_t offset;
	ctable_header meta;
	rofile * meta_file;
	
	if(base)
		deinit();
	factory = dtable_factory::lookup(config, "base");
	if(!factory)
		return -ENOENT;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	ct_dfd = openat(dfd, file, O_RDONLY);
	if(ct_dfd < 0)
		return ct_dfd;
	
	meta_file = rofile::open<4, 2>(ct_dfd, "sct_meta");
	if(!meta_file)
		goto fail_open;
	r = meta_file->read_type(0, &meta);
	if(r < 0)
		goto fail_header;
	if(meta.magic != SIMPLE_CTABLE_MAGIC || meta.version != SIMPLE_CTABLE_VERSION)
		goto fail_header;
	column_count = meta.columns;
	
	column_name = new istr[column_count];
	if(!column_name)
		goto fail_header;
	
	offset = sizeof(meta);
	for(size_t i = 0; i < column_count; i++)
	{
		uint32_t length;
		r = meta_file->read_type(offset, &length);
		if(r < 0)
			goto fail_names;
		offset += sizeof(length);
		column_name[i] = meta_file->read_string(offset, length);
		if(!column_name[i])
			goto fail_names;
		offset += length;
		column_map[column_name[i]] = i;
	}
	
	base = factory->open(ct_dfd, "base", base_config, sysj);
	if(!base)
		goto fail_names;
	ktype = base->key_type();
	cmp_name = base->get_cmp_name();
	
	delete meta_file;
	close(ct_dfd);
	return 0;
	
fail_names:
	column_map.empty();
	delete[] column_name;
fail_header:
	delete meta_file;
fail_open:
	close(ct_dfd);
	return -1;
}
Пример #16
0
int keydiv_dtable::create(int dfd, const char * name, const params & config, dtype::ctype key_type)
{
	int r, kdd_dfd, meta;
	divider_list dividers;
	const dtable_factory * base;
	params base_config;
	
	kddtable_header header;
	header.magic = KDDTABLE_MAGIC;
	header.version = KDDTABLE_VERSION;
	switch(key_type)
	{
		case dtype::UINT32:
			header.key_type = 1;
			r = load_dividers<int, uint32_t>(config, 0, &dividers);
			break;
		case dtype::DOUBLE:
			header.key_type = 2;
			r = load_dividers<float, double>(config, 0, &dividers);
			break;
		case dtype::STRING:
			header.key_type = 3;
			r = load_dividers<istr, istr>(config, 0, &dividers);
			break;
		case dtype::BLOB:
			header.key_type = 4;
			r = load_dividers<blob, blob>(config, 0, &dividers, true);
			break;
		default:
			return -EINVAL;
	}
	header.dt_count = dividers.size() + 1;
	/* make sure we don't overflow the header field */
	if(header.dt_count != dividers.size() + 1)
		return -EINVAL;
	
	base = dtable_factory::lookup(config, "base");
	if(!base)
		return -EINVAL;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	
	r = mkdirat(dfd, name, 0755);
	if(r < 0)
		return r;
	kdd_dfd = openat(dfd, name, O_RDONLY);
	if(kdd_dfd < 0)
	{
		unlinkat(dfd, name, AT_REMOVEDIR);
		return kdd_dfd;
	}
	
	for(uint32_t i = 0; i < header.dt_count; i++)
	{
		char name[32];
		sprintf(name, "kdd_data.%u", i);
		r = base->create(kdd_dfd, name, base_config, key_type);
		if(r < 0)
			goto fail;
	}
	
	meta = openat(kdd_dfd, "kdd_meta", O_WRONLY | O_CREAT, 0644);
	if(meta < 0)
	{
		r = meta;
		goto fail;
	}
	r = pwrite(meta, &header, sizeof(header), 0);
	close(meta);
	if(r != sizeof(header))
		goto fail;
	close(kdd_dfd);
	return 0;
	
fail:
	close(kdd_dfd);
	util::rm_r(dfd, name);
	return (r < 0) ? r : -1;
}
Пример #17
0
int keydiv_dtable::init(int dfd, const char * name, const params & config, sys_journal * sysj)
{
	abortable_tx atx;
	int r, kdd_dfd, meta;
	const dtable_factory * base;
	params base_config;
	if(sub.size() >= 0)
		deinit();
	base = dtable_factory::lookup(config, "base");
	if(!base)
		return -EINVAL;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	kdd_dfd = openat(dfd, name, O_RDONLY);
	if(kdd_dfd < 0)
		return kdd_dfd;
	meta = openat(kdd_dfd, "kdd_meta", O_RDONLY);
	if(meta < 0)
		goto fail_meta;
	
	if(pread(meta, &header, sizeof(header), 0) != sizeof(header))
	{
		close(meta);
		goto fail_meta;
	}
	close(meta);
	if(header.magic != KDDTABLE_MAGIC || header.version != KDDTABLE_VERSION)
		goto fail_meta;
	if(!header.dt_count)
		goto fail_meta;
	switch(header.key_type)
	{
		case 1:
			ktype = dtype::UINT32;
			r = load_dividers<int, uint32_t>(config, header.dt_count, &dividers);
			break;
		case 2:
			ktype = dtype::DOUBLE;
			r = load_dividers<float, double>(config, header.dt_count, &dividers);
			break;
		case 3:
			ktype = dtype::STRING;
			r = load_dividers<istr, istr>(config, header.dt_count, &dividers);
			break;
		case 4:
			ktype = dtype::BLOB;
			r = load_dividers<blob, blob>(config, header.dt_count, &dividers, true);
			break;
		default:
			goto fail_meta;
	}
	if(r < 0)
		goto fail_meta;
	
	for(uint32_t i = 0; i < header.dt_count; i++)
	{
		char name[32];
		dtable * source;
		sprintf(name, "kdd_data.%u", i);
		source = base->open(kdd_dfd, name, base_config, sysj);
		if(!source)
			goto fail_sub;
		sub.push_back(source);
	}
	
	if(sub[0]->get_cmp_name())
		cmp_name = sub[0]->get_cmp_name();
	
	/* check for abortable transaction support */
	atx = sub[0]->create_tx();
	if((support_atx = (atx != NO_ABORTABLE_TX)))
		sub[0]->abort_tx(atx);
	
	return 0;
	
fail_sub:
	for(size_t i = 0; i < sub.size(); i++)
		sub[i]->destroy();
fail_meta:
	sub.clear();
	dividers.clear();
	close(kdd_dfd);
	return -1;
}
Пример #18
0
int deltaint_dtable::create(int dfd, const char * file, const params & config, dtable::iter * source, const ktable * shadow)
{
	int r, di_dfd, skip;
	rev_iter_delta * rev;
	rev_iter_ref * ref;
	params base_config, ref_config;
	const dtable_factory * base = dtable_factory::lookup(config, "base");
	const dtable_factory * reference = dtable_factory::lookup(config, "ref");
	if(!base || !reference)
		return -ENOENT;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	if(!config.get("ref_config", &ref_config, params()))
		return -EINVAL;
	if(!config.get("skip", &skip, 0) || skip < 2)
		return -EINVAL;
	
	if(!source_shadow_ok(source, shadow))
		return -EINVAL;
	
	r = mkdirat(dfd, file, 0755);
	if(r < 0)
		return r;
	di_dfd = openat(dfd, file, O_RDONLY);
	if(di_dfd < 0)
		goto fail_open;
	
	rev = new rev_iter_delta(source);
	if(!rev)
	{
		r = -ENOMEM;
		goto fail_iter_1;
	}
	r = base->create(di_dfd, "base", base_config, rev, shadow);
	if(r < 0)
		goto fail_create_1;
	if(rev->failed)
	{
		r = -ENOSYS;
		goto fail_iter_2;
	}
	
	ref = new rev_iter_ref(source, skip);
	if(!ref)
	{
		r = -ENOMEM;
		goto fail_iter_2;
	}
	r = reference->create(di_dfd, "ref", ref_config, ref, NULL);
	if(r < 0)
		goto fail_create_2;
	
	delete ref;
	delete rev;
	close(di_dfd);
	return r;
	
fail_create_2:
	delete ref;
fail_iter_2:
	util::rm_r(di_dfd, "base");
fail_create_1:
	delete rev;
fail_iter_1:
	close(di_dfd);
fail_open:
	unlinkat(dfd, file, AT_REMOVEDIR);
	return (r < 0) ? r : -1;
}
Пример #19
0
int exception_dtable::create(int dfd, const char * file, const params & config, dtable::iter * source, const ktable * shadow)
{
	int excp_dfd, r;
	memory_dtable alt_mdt;
	reject_iter * handler;
	params base_config, alt_config;
	blob reject_value;
	const dtable_factory * base = dtable_factory::lookup(config, "base");
	const dtable_factory * alt = dtable_factory::lookup(config, "alt");
	if(!base || !alt)
		return -EINVAL;
	if(!config.get("base_config", &base_config, params()))
		return -EINVAL;
	if(!config.get("alt_config", &alt_config, params()))
		return -EINVAL;
	if(!config.get_blob_or_string("reject_value", &reject_value))
		return -EINVAL;
	/* the reject value must exist, because nonexistent values
	 * can get pruned out if the shadow does not require them */
	if(!reject_value.exists())
		return -EINVAL;
	
	if(!source_shadow_ok(source, shadow))
		return -EINVAL;
	
	r = mkdirat(dfd, file, 0755);
	if(r < 0)
		return r;
	excp_dfd = openat(dfd, file, O_RDONLY);
	if(excp_dfd < 0)
		goto fail_open;
	/* we should really save the reject_value in a meta file here */
	
	/* we'll always be appending, but it's faster if we say false here */
	r = alt_mdt.init(source->key_type(), false, true);
	if(r < 0)
		goto fail_mdt;
	if(source->get_blob_cmp())
		alt_mdt.set_blob_cmp(source->get_blob_cmp());
	
	handler = new reject_iter(source, &alt_mdt, reject_value);
	if(!handler)
		goto fail_mdt;
	
	r = base->create(excp_dfd, "base", base_config, handler, shadow);
	if(r < 0)
		goto fail_base;
	
	/* no shadow - this only has exceptions */
	r = alt->create(excp_dfd, "alt", alt_config, &alt_mdt, NULL);
	if(r < 0)
		goto fail_alt;
	
	delete handler;
	close(excp_dfd);
	return 0;
	
fail_alt:
	util::rm_r(excp_dfd, "base");
fail_base:
	delete handler;
fail_mdt:
	close(excp_dfd);
fail_open:
	unlinkat(dfd, file, AT_REMOVEDIR);
	return -1;
}