blob: 6c15cb45755b64f5088ed029c2d40a776e04e676 [file] [log] [blame]
/* AUTORIGHTS
Copyright (C) 2007 Princeton University
This file is part of Ferret Toolkit.
Ferret Toolkit is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* wdong */
#include <string.h>
#include <unistd.h>
#include <cass.h>
int cass_table_create (cass_table_t **_table,
cass_env_t *env, // See management section
char *table_name,
uint32_t opr_idx,
int32_t cfg_id,
int32_t parent_id,
int32_t parent_cfg_id,
int32_t map_id,
char *param)
{
char buf[BUFSIZ];
int ret;
ret = CASS_ERR_OUTOFMEM;
cass_table_t *table = type_calloc(cass_table_t, 1);
if (table == NULL) goto err;
table->refcnt = 1;
table->name = strdup(table_name);
if (table->name == NULL) goto err;
table->env = env;
table->parent_id = parent_id;
table->cfg_id = cfg_id;
table->parent_cfg_id = parent_cfg_id;
table->map_id = map_id;
ARRAY_INIT(table->child_ids);
table->opr = cass_table_opr_get(opr_idx);
sprintf(buf, "%s/%s.%s", env->base_dir, table_name, table->opr->name);
table->filename = strdup(buf);
table->loaded = 0;
table->dirty = 0;
ret = __cass_table_ref(table); /* fill the pointers, create children list */
if (ret != 0) goto err;
ret = table->opr->init_private(table, param);
if (ret != 0) goto err;
*_table = table;
return 0;
err:
if (table != NULL) cass_table_free(table);
return ret;
}
int cass_table_associate(cass_table_t *table,
int32_t tbl2)
{
cass_table_t *ptbl2 = cass_reg_get(&table->env->table, tbl2);
assert(ptbl2 != NULL);
ARRAY_APPEND(table->child_ids, tbl2);
ARRAY_APPEND(table->children, ptbl2);
assert(table->children.len == table->child_ids.len);
ptbl2->parent_id = cass_reg_find(&table->env->table, table);
ptbl2->parent_cfg_id = table->cfg_id;
ptbl2->parent_cfg = table->cfg;
ptbl2->parent_cfg->refcnt++;
ptbl2->refcnt++;
return 0;
}
int cass_table_disassociate(cass_table_t *table,
int32_t tbl2)
{
int i;
cass_table_t *ptbl2 = cass_reg_get(&table->env->table, tbl2);
assert(ptbl2 != NULL);
for (i = 0; i < table->children.len; i++) if (table->children.data[i] == ptbl2) break;
for (; i < table->child_ids.len - 1; i++)
{
table->children.data[i] = table->children.data[i+1];
table->child_ids.data[i] = table->child_ids.data[i+1];
}
table->child_ids.len--;
table->children.len--;
assert(table->children.len == table->child_ids.len);
cass_table_free(ptbl2);
cass_vecset_cfg_free(ptbl2->parent_cfg);
return 0;
}
int cass_table_free(cass_table_t *table)
{
assert(table != NULL);
table->refcnt--;
if (table->refcnt > 0) return 0;
assert(!table->dirty);
__cass_table_unref(table);
if (table->__private != NULL) table->opr->free_private(table);
ARRAY_CLEANUP(table->child_ids);
if (table->name != NULL) free(table->name);
if (table->filename != NULL) free(table->filename);
free(table);
return 0;
}
int cass_table_restore (cass_table_t **_table, cass_env_t *env, CASS_FILE *in)
{
int ret;
uint32_t n, c;
ret = CASS_ERR_OUTOFMEM;
cass_table_t *table = type_calloc(cass_table_t, 1);
if (table == NULL) goto err;
table->env = env;
table->refcnt++;
table->name = cass_read_pchar(in);
if (table->name == NULL) goto err;
char buf[BUFSIZ];
ret = CASS_ERR_IO;
//if (cass_read_uint32_t(&table->self_id, 1, in) != 1) goto err;
if (cass_read_int32(&table->parent_id, 1, in) != 1) goto err;
if (cass_read_int32(&table->cfg_id, 1, in) != 1) goto err;
if (cass_read_int32(&table->parent_cfg_id, 1, in) != 1) goto err;
if (cass_read_int32(&table->map_id, 1, in) != 1) goto err;
if (cass_read_size(&n, 1, in) != 1) goto err;
ret = CASS_ERR_OUTOFMEM;
ARRAY_INIT_SIZE(table->child_ids, n);
if (n != 0 && table->child_ids.data == NULL) goto err;
ret = CASS_ERR_IO;
if (n > 0)
{
if (cass_read_int32((int32_t *)table->child_ids.data, n, in) != n) goto err;
table->child_ids.len = n;
}
if (cass_read_uint32(&c, 1, in) != 1) goto err;
table->opr = cass_table_opr_get(c);
assert(table->opr != NULL);
sprintf(buf, "%s/%s.%s", env->base_dir, table->name, table->opr->name);
table->filename = strdup(buf);
table->loaded = table->dirty = 0;
ret = table->opr->restore_private(table, in);
if (ret != 0) goto err;
*_table = table;
return 0;
err:
if (table != NULL) cass_table_free(table);
return ret;
}
int cass_table_checkpoint (cass_table_t *table, CASS_FILE *out)
{
uint32_t c;
int ret;
if (cass_write_pchar(table->name, out) != 0) return CASS_ERR_IO;
//if (cass_write_uint32_t(&table->self_id, 1, out) != 1) return CASS_ERR_IO;
if (cass_write_int32(&table->parent_id, 1, out) != 1) return CASS_ERR_IO;
if (cass_write_int32(&table->cfg_id, 1, out) != 1) return CASS_ERR_IO;
if (cass_write_int32(&table->parent_cfg_id, 1, out) != 1) return CASS_ERR_IO;
if (cass_write_int32(&table->map_id, 1, out) != 1) return CASS_ERR_IO;
if (cass_write_size(&table->child_ids.len, 1, out) != 1) return CASS_ERR_IO;
if (cass_write_int32(table->child_ids.data, table->child_ids.len, out) != table->children.len) return CASS_ERR_IO;
c = cass_table_opr_find(table->opr);
if (cass_write_uint32(&c, 1, out) != 1) return CASS_ERR_IO;
ret = table->opr->checkpoint_private(table, out);
if (ret == 0) table->dirty = 0;
return ret;
}
/*
int cass_table_insert (cass_table_t *table,
cass_vecset_id_t id,
cass_vecset_t *vecset)
{
ARRAY_BEGIN_FOREACH(table->children, p)
{
cass_table_insert(p, id, vecset);
} ARRAY_END_FOREACH(table->children, p);
return table->opr->insert(table, id, vecset);
}
*/
int cass_table_batch_insert(cass_table_t *table, cass_dataset_t * parent, cass_vecset_id_t start, cass_vecset_id_t end)
{
int ret = 0;
ARRAY_BEGIN_FOREACH(table->children, cass_table_t *p)
{
ret = cass_table_batch_insert(p, parent, start, end);
if (ret != 0) return ret;
} ARRAY_END_FOREACH;
assert(table->opr->batch_insert != NULL);
table->dirty = 1;
return table->opr->batch_insert(table, parent, start, end);
}
int cass_table_describe (cass_table_t *table, CASS_FILE *out)
{
cass_printf(out, "NAME:\t%s\n", table->name);
cass_printf(out, "CLASS:\t%s\n", table->opr->name);
if (table->cfg == NULL)
{
cass_printf(out, "CONFIG: (none, the table is sketch/index.)");
}
else
{
cass_printf(out, "CONFIG:\t%s\n", table->cfg->name);
}
/*
{
cass_vecset_dist_t *p = (cass_vecset_dist_t *)cass_reg_get(&table->env->vecset_dist, table->vecset_dist_id);
assert(p != NULL);
cass_printf(out, "VECSET DIST:\t%s\n", p->name);
}
{
cass_vec_dist_t *p = (cass_vec_dist_t *)cass_reg_get(&table->env->vec_dist, table->vec_dist_id);
assert(p != NULL);
cass_printf(out, "VEC DIST:\t%s\n", p->name);
}
*/
cass_printf(out, "MAP:\t");
if (table->map_id == -1)
{
cass_printf(out, "(none)\n");
}
else
{
cass_map_t *p = (cass_map_t *)cass_reg_get(&table->env->map, table->map_id);
assert(p != NULL);
cass_printf(out, "%s\n", p->name);
}
cass_printf(out, "PARENT:\t");
if (table->parent_id == -1)
{
cass_printf(out, "(none)\n");
}
else
{
cass_table_t *p = (cass_table_t *)cass_reg_get(&table->env->table, table->parent_id);
assert(p != NULL);
cass_printf(out, "%s\n", p->name);
}
cass_printf(out, "CHILDREN:");
ARRAY_BEGIN_FOREACH(table->children, cass_table_t *p)
{
cass_printf(out, "\t%s", p->name);
} ARRAY_END_FOREACH;
cass_printf(out, "\n");
return 0;
}
cass_table_t *cass_table_parent (cass_table_t *table)
{
cass_env_t *env = table->env;
assert(env != NULL);
if (table->parent_id < 0) return NULL;
return cass_reg_get(&env->table, table->parent_id);
}
int cass_table_drop (cass_table_t *table)
{
return unlink(table->filename);
}
int cass_table_query (cass_table_t *table,
cass_query_t *query, cass_result_t *result)
{
if (table->opr->query != NULL) return table->opr->query(table, query, result);
else
{
assert(table->opr->batch_query != NULL);
return table->opr->batch_query(table, 1, &query, &result);
}
}
int cass_table_batch_query (cass_table_t *table, uint32_t count,
cass_query_t **queries,
cass_result_t **results)
{
if (table->opr->batch_query != NULL) return table->opr->batch_query(table, count, queries, results);
else
{
int i;
assert(table->opr->query != NULL);
for (i = 0; i < count; i++)
{
table->opr->query(table, queries[i], results[i]);
}
}
return 0;
}