Commit 9ad057ed authored by Per Cederqvist's avatar Per Cederqvist
Browse files

(find_block_index_key_reverse): New static function.

(l2gi_searchsome_reverse): New function.
(l2gi_prev): New function.
parent 7f70c998
...@@ -445,6 +445,93 @@ find_block_index_key(const Local_to_global *l2g, Local_text_no lno, ...@@ -445,6 +445,93 @@ find_block_index_key(const Local_to_global *l2g, Local_text_no lno,
restart_kom("find_block_index_key found nothing\n"); restart_kom("find_block_index_key found nothing\n");
} }
/* Find the first local text number lower than LNO and return it.
Return 0 if LNO is lower than any local text number in the
structure. The block where the returned value was found is stored
in BINFO_OUT, and the position within the block is stored in
INDEX_OUT. BINFO_OUT and INDEX_OUT are only filled in if the
return value is non-zero. */
static Local_text_no
find_block_index_key_reverse(const Local_to_global *l2g,
Local_text_no lno,
const struct l2g_block_info **binfo_out,
int *index_out)
{
const struct l2g_block_info *binfo;
int i;
/* Adjust lno to the local number we are hunting for. */
if (lno > 0)
--lno;
/* If the number is not to be found, return 0. */
binfo = find_block(l2g, lno);
if (binfo == NULL)
return 0;
/* Check if not present in the first block. */
if (lno < binfo->start)
return 0;
/* Check the found block and return the last entry found, if any. */
if (is_dense(binfo))
{
i = lno - binfo->start;
if (i >= binfo->first_free)
i = binfo->first_free - 1;
for (; i >= 0; --i)
if (binfo->value_block[i] != 0)
{
*binfo_out = binfo;
*index_out = i;
return binfo->start + i;
}
}
else
{
i = sparse_locate_value(binfo, lno);
if (i >= binfo->first_free)
i = binfo->first_free - 1;
while (i > 0 && (binfo->value_block[i] == 0
|| binfo->key_block[i] > lno))
{
++sparse_skip_cost;
--i;
}
if (binfo->value_block[i] != 0 && binfo->key_block[i] <= lno)
{
*binfo_out = binfo;
*index_out = i;
return binfo->key_block[i];
}
}
/*
* Try the previous block, if there is one.
*/
if (binfo == l2g->blocks)
return 0;
binfo--;
/*
* We want the last existing entry in the block that binfo points
* to.
*/
for (i = binfo->first_free - 1; i >= 0; --i)
if (binfo->value_block[i] != 0)
{
*binfo_out = binfo;
*index_out = i;
return key_value(binfo, i);
}
restart_kom("find_block_index_key_reverse found nothing\n");
}
static void static void
join_range(Local_to_global *l2g, join_range(Local_to_global *l2g,
struct l2g_block_info *first, struct l2g_block_info *first,
...@@ -1328,6 +1415,82 @@ l2gi_end(const L2g_iterator *l2gi) ...@@ -1328,6 +1415,82 @@ l2gi_end(const L2g_iterator *l2gi)
} }
/* ================================================================ */
/* === Reverse Iterator code === */
/* ================================================================ */
void
l2gi_searchsome_reverse(L2g_reverse_iterator *l2gi,
const Local_to_global *l2g,
Local_text_no begin,
Local_text_no end)
{
const struct l2g_block_info * binfo;
int index;
l2gi->l2g = l2g;
l2gi->beginval = begin;
l2gi->endval = end;
l2gi->search_ended = 1;
if (begin >= end)
return;
if (find_block_index_key_reverse(l2g, end, &binfo, &index) == 0)
return;
l2gi->binfo = binfo;
l2gi->arrindex = index;
assert(binfo != NULL);
l2gi->lno = key_value(binfo, index);
l2gi->tno = binfo->value_block[index];
l2gi->search_ended = l2gi->lno < begin;
}
void
l2gi_prev(L2g_reverse_iterator *l2gi)
{
const Local_to_global *l2g;
const struct l2g_block_info *binfo;
int arrindex;
l2g = l2gi->l2g;
arrindex = l2gi->arrindex - 1;
for (binfo = l2gi->binfo;
binfo >= l2g->blocks;
--binfo, arrindex = binfo->first_free - 1)
{
for (; arrindex >= 0; --arrindex)
{
if (key_value(binfo, arrindex) < l2gi->beginval)
{
l2gi->search_ended = 1;
return;
}
if (binfo->value_block[arrindex] != 0)
{
l2gi->binfo = binfo;
l2gi->arrindex = arrindex;
l2gi->lno = key_value(binfo, arrindex);
l2gi->tno = binfo->value_block[arrindex];
return;
}
}
}
l2gi->search_ended = 1;
return;
}
/* ---------- */ /* ---------- */
extern void extern void
......
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