Commit 1e4e46d7 authored by Nicolas Denoyelle's avatar Nicolas Denoyelle

add indexer to tree levels

parent 7ec342e1
...@@ -416,7 +416,11 @@ enum tleaf_it_policy_e { ...@@ -416,7 +416,11 @@ enum tleaf_it_policy_e {
* Initialize a tleaf iterator by giving its depth, levels arity and iteration policy. * Initialize a tleaf iterator by giving its depth, levels arity and iteration policy.
* "it": a tleaf iterator * "it": a tleaf iterator
* "depth": the total number of levels of the tree, including leaves * "depth": the total number of levels of the tree, including leaves
* "arity": An array of size (depth-1). For each level, the number of children attached to a node. Leaves have no children, hence last level arity is ignored. Arities are organized from root to leaves. * "arity": An array of size (depth-1). For each level, the number of children attached to a node.
* Leaves have no children. Arities are organized from root to leaves.
* "index": NULL or an array of depth excit_t to re-index levels.
* It is intended to prune node of certain levels while keeping index of the initial structure.
* Ownership of index is not taken. The iterator allocates a copy of index and manage it internally.
* "policy": A policy for iteration on leaves. * "policy": A policy for iteration on leaves.
* "user_policy": If policy is TLEAF_POLICY_USER, then this argument must be an array of size (depth-1) providing the order (from 0 to (depth-2)) in wich levels are walked. * "user_policy": If policy is TLEAF_POLICY_USER, then this argument must be an array of size (depth-1) providing the order (from 0 to (depth-2)) in wich levels are walked.
* when resolving indexes. Underneath, a product iterator of range iterator returns indexes on last levels upon iterator queries. This set of indexes is then * when resolving indexes. Underneath, a product iterator of range iterator returns indexes on last levels upon iterator queries. This set of indexes is then
...@@ -427,6 +431,7 @@ enum tleaf_it_policy_e { ...@@ -427,6 +431,7 @@ enum tleaf_it_policy_e {
int excit_tleaf_init(excit_t it, int excit_tleaf_init(excit_t it,
const ssize_t depth, const ssize_t depth,
const ssize_t *arities, const ssize_t *arities,
excit_t *index,
const enum tleaf_it_policy_e policy, const enum tleaf_it_policy_e policy,
const ssize_t *user_policy); const ssize_t *user_policy);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
static int tleaf_init_with_it(excit_t it, static int tleaf_init_with_it(excit_t it,
const ssize_t depth, const ssize_t depth,
const ssize_t *arities, const ssize_t *arities,
excit_t *indexes,
const enum tleaf_it_policy_e policy, const enum tleaf_it_policy_e policy,
const ssize_t *user_policy, const ssize_t *user_policy,
excit_t levels, excit_t levels_inverse); excit_t levels, excit_t levels_inverse);
...@@ -87,7 +88,7 @@ static int tleaf_it_copy(excit_t dst_it, const excit_t src_it) ...@@ -87,7 +88,7 @@ static int tleaf_it_copy(excit_t dst_it, const excit_t src_it)
goto error_with_levels; goto error_with_levels;
} }
err = tleaf_init_with_it(dst_it, src->depth + 1, src->arities, err = tleaf_init_with_it(dst_it, src->depth + 1, src->arities, NULL,
TLEAF_POLICY_USER, src->order, levels, TLEAF_POLICY_USER, src->order, levels,
levels_inverse); levels_inverse);
if (err != EXCIT_SUCCESS) if (err != EXCIT_SUCCESS)
...@@ -178,7 +179,7 @@ int tleaf_it_rank(const excit_t it, const ssize_t *indexes, ssize_t *n) ...@@ -178,7 +179,7 @@ int tleaf_it_rank(const excit_t it, const ssize_t *indexes, ssize_t *n)
ssize_t i, acc = 1, val = 0; ssize_t i, acc = 1, val = 0;
for (i = data_it->depth-1; i >= 0 ; i--) { for (i = data_it->depth - 1; i >= 0; i--) {
val += acc * data_it->buf[data_it->order_inverse[i]]; val += acc * data_it->buf[data_it->order_inverse[i]];
acc *= data_it->arities[i]; acc *= data_it->arities[i];
} }
...@@ -187,31 +188,74 @@ int tleaf_it_rank(const excit_t it, const ssize_t *indexes, ssize_t *n) ...@@ -187,31 +188,74 @@ int tleaf_it_rank(const excit_t it, const ssize_t *indexes, ssize_t *n)
return EXCIT_SUCCESS; return EXCIT_SUCCESS;
} }
static int tleaf_add_level(excit_t levels, const ssize_t arity) int tleaf_it_make_levels(struct tleaf_it_s *tleaf, excit_t *indexes,
ssize_t *order, excit_t *levels)
{ {
excit_t level = excit_alloc(EXCIT_RANGE); ssize_t i;
int err;
excit_t index, range, comp;
if (level == NULL) *levels = excit_alloc(EXCIT_PRODUCT);
if (*levels == NULL)
return -EXCIT_ENOMEM; return -EXCIT_ENOMEM;
int err = excit_range_init(level, 0, arity - 1, 1); for (i = 0; i < tleaf->depth; i++) {
ssize_t l = order[i];
if (err != EXCIT_SUCCESS) index = indexes == NULL ? NULL : indexes[l];
goto error;
err = excit_product_add(levels, level); range = excit_alloc(EXCIT_RANGE);
if (err != EXCIT_SUCCESS)
goto error; if (range == NULL) {
err = -EXCIT_ENOMEM;
goto error_with_levels;
}
err = excit_range_init(range, 0, tleaf->arities[l] - 1, 1);
if (err != EXCIT_SUCCESS)
goto error_with_range;
if (index != NULL) {
comp = excit_alloc(EXCIT_COMPOSITION);
if (comp == NULL) {
err = -EXCIT_ENOMEM;
goto error_with_range;
}
index = excit_dup(index);
if (index == NULL) {
err = -EXCIT_ENOMEM;
goto error_with_comp;
}
err = excit_composition_init(comp, range, index);
if (err != EXCIT_SUCCESS)
goto error_with_index;
err = excit_product_add(*levels, comp);
if (err != EXCIT_SUCCESS)
goto error_with_index;
} else {
err = excit_product_add(*levels, range);
if (err != EXCIT_SUCCESS)
goto error_with_range;
}
}
return EXCIT_SUCCESS; return EXCIT_SUCCESS;
error:
excit_free(level); error_with_index:
excit_free(index);
error_with_comp:
excit_free(comp);
error_with_range:
excit_free(range);
error_with_levels:
excit_free(*levels);
*levels = NULL;
return err; return err;
} }
static int tleaf_init_with_it(excit_t it, static int tleaf_init_with_it(excit_t it,
const ssize_t depth, const ssize_t depth,
const ssize_t *arities, const ssize_t *arities,
excit_t *indexes,
const enum tleaf_it_policy_e policy, const enum tleaf_it_policy_e policy,
const ssize_t *user_policy, const ssize_t *user_policy,
excit_t levels, excit_t levels_inverse) excit_t levels, excit_t levels_inverse)
...@@ -275,48 +319,25 @@ static int tleaf_init_with_it(excit_t it, ...@@ -275,48 +319,25 @@ static int tleaf_init_with_it(excit_t it,
} }
/* Set product iterator if not provided */ /* Set product iterator if not provided */
if (levels == NULL) { data_it->levels = levels;
data_it->levels = excit_alloc(EXCIT_PRODUCT); data_it->levels_inverse = levels_inverse;
if (data_it->levels == NULL) { if (levels == NULL)
err = -EXCIT_ENOMEM; err =
goto error_with_buf; tleaf_it_make_levels(data_it, indexes, data_it->order,
} &(data_it->levels));
if (err != EXCIT_SUCCESS)
for (i = 0; i < data_it->depth; i++) { goto error_with_buf;
ssize_t l = data_it->order[i];
err = tleaf_add_level(data_it->levels,
data_it->arities[l]);
if (err != EXCIT_SUCCESS)
goto error_with_levels;
}
} else {
data_it->levels = levels;
}
if (levels_inverse == NULL) {
data_it->levels_inverse = excit_alloc(EXCIT_PRODUCT);
if (data_it->levels_inverse == NULL) {
err = -EXCIT_ENOMEM;
goto error_with_levels;
}
for (i = 0; i < data_it->depth; i++) {
ssize_t l = data_it->order_inverse[i];
err = tleaf_add_level(data_it->levels_inverse, if (levels_inverse == NULL)
data_it->arities[l]); err =
if (err != EXCIT_SUCCESS) tleaf_it_make_levels(data_it, indexes,
goto error_with_levels_inverse; data_it->order_inverse,
} &(data_it->levels_inverse));
} else { if (err != EXCIT_SUCCESS)
data_it->levels_inverse = levels_inverse; goto error_with_levels;
}
return EXCIT_SUCCESS; return EXCIT_SUCCESS;
error_with_levels_inverse:
excit_free(data_it->levels_inverse);
data_it->levels_inverse = NULL;
error_with_levels: error_with_levels:
excit_free(data_it->levels); excit_free(data_it->levels);
data_it->levels = NULL; data_it->levels = NULL;
...@@ -339,11 +360,12 @@ error: ...@@ -339,11 +360,12 @@ error:
int excit_tleaf_init(excit_t it, int excit_tleaf_init(excit_t it,
const ssize_t depth, const ssize_t depth,
const ssize_t *arities, const ssize_t *arities,
excit_t *indexes,
const enum tleaf_it_policy_e policy, const enum tleaf_it_policy_e policy,
const ssize_t *user_policy) const ssize_t *user_policy)
{ {
return tleaf_init_with_it(it, depth, arities, policy, user_policy, return tleaf_init_with_it(it, depth, arities, indexes, policy,
NULL, NULL); user_policy, NULL, NULL);
} }
int tleaf_split_levels(excit_t levels, const ssize_t depth, const ssize_t n, int tleaf_split_levels(excit_t levels, const ssize_t depth, const ssize_t n,
...@@ -403,6 +425,7 @@ int tleaf_it_split(const excit_t it, const ssize_t depth, ...@@ -403,6 +425,7 @@ int tleaf_it_split(const excit_t it, const ssize_t depth,
err = tleaf_init_with_it(out[i], err = tleaf_init_with_it(out[i],
data_it->depth + 1, data_it->depth + 1,
data_it->arities, data_it->arities,
NULL,
TLEAF_POLICY_USER, TLEAF_POLICY_USER,
data_it->order, levels[i], data_it->order, levels[i],
levels_inverse[i]); levels_inverse[i]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment