Commit cf8c5ea6 authored by inge's avatar inge

- Implement file reading and writing: l2g_read, l2g_write

- Make the following more efficient: l2g_copy
- Bug fixes: l2g_clear, l2g_delete
parent d81c90f3
......@@ -18,6 +18,9 @@
#include "kom-types.h"
#include "local-to-global.h"
#include "log.h"
#include "ram-parse.h"
#include "ram-output.h"
/* ================================================================ */
......@@ -56,6 +59,30 @@ add_block(Local_to_global *l2g)
}
/*
* Delete a block from the Local_to_global L2G. The pointer BINFO
* points at the block, which is supposed to be empty.
*/
static void
delete_block(Local_to_global *l2g,
L2g_block_info *binfo)
{
/* Remove the blocks from the Block Info */
if (binfo->key_block != NULL)
free(binfo->key_block);
free(binfo->value_block);
/* Compact the remaining blocks. */
while (++binfo < l2g->blocks + l2g->num_blocks)
*(binfo - 1) = *binfo;
l2g->num_blocks--;
l2g->blocks = (L2g_block_info *)
realloc(l2g->blocks,
l2g->num_blocks * sizeof(L2g_block_info));
}
/*
* Make a sparse block from a dense one.
*/
......@@ -144,9 +171,6 @@ void
l2g_destruct(Local_to_global *l2g)
{
l2g_clear(l2g);
/* Free the block pointers */
free(l2g->blocks);
}
......@@ -183,10 +207,12 @@ l2g_clear(Local_to_global *l2g)
binfo++;
}
/* Free the block pointers except the first one. */
/* Free the block pointers. */
l2g->num_blocks = 0;
free(l2g->blocks);
l2g->blocks = NULL;
if (l2g->blocks != NULL) {
free(l2g->blocks);
l2g->blocks = NULL;
}
}
......@@ -258,8 +284,8 @@ l2g_append(Local_to_global *l2g,
&& lno - binfo->start >= L2G_BLOCKSIZE){
/*
* If the last block is dense, and LNO is outside the block,
* see if we should convert it to a sparse block or if we should
* allocate a new one.
* check if we should convert it to a sparse block or if we
* should allocate a new one.
*/
if ((L2G_BLOCKSIZE - binfo->first_free)
+ binfo->zeroes > L2G_BLOCKSIZE / 2) {
......@@ -325,6 +351,14 @@ l2g_delete(Local_to_global *l2g, Local_text_no lno)
}
}
}
/* Delete the block if it is empty. */
/* NOTE, FIXME: Check what this does to iterators, and maybe */
/* find some other way. Perhaps we could set */
/* next_free to -1 or something and then remove */
/* the blocks only when compact() is called. */
if (binfo->zeroes == L2G_BLOCKSIZE)
delete_block(l2g, binfo);
}
......@@ -347,14 +381,12 @@ l2g_lookup(Local_to_global *l2g, Local_text_no lno)
/* A dense block */
if (binfo->start <= lno && lno < binfo->start + L2G_BLOCKSIZE)
return binfo->value_block[lno - binfo->start];
return 0;
} else {
/* FIXME: Binary search */
for (i = 0; i < binfo->first_free && binfo->key_block[i] <= lno; ++i) {
if (binfo->key_block[i] == lno)
return binfo->value_block[i];
}
return 0;
}
return 0;
......@@ -437,8 +469,8 @@ l2g_compact(Local_to_global *l2g)
l2g_init(&dummy);
l2g_copy(l2g, &dummy);
l2g_copy(&dummy, l2g);
l2g_destruct(&dummy);
l2g_destruct(l2g);
*l2g = dummy;
}
......@@ -483,20 +515,74 @@ l2g_dump(Local_to_global *l2g, FILE *file)
/*
*
* Read a Local to global structure from the file FILE.
*/
void
l2g_read(Local_to_global *l2g, FILE *file)
l2g_read(Local_to_global *l2g, FILE *fp)
{
int c;
Local_text_no lno;
Text_no tno;
/* Read past the start marker */
fskipwhite(fp);
if ( (c = getc(fp)) == EOF || c != '[') {
log("l2g_read() failed at pos %lu.\n", (unsigned long) ftell(fp));
return;
}
/* Read pairs of numbers until the EOL (end-of-l2g :-) ) marker is read. */
while (1) {
fskipwhite(fp);
if ((c = getc(fp)) == ']')
break;
else
ungetc(c, fp);
lno = (Local_text_no) fparse_long(fp);
tno = (Text_no) fparse_long(fp);
l2g_append(l2g, lno, tno);
}
}
/*
*
* Print the structure to the file FILE.
*/
void
l2g_print(Local_to_global *l2g, FILE *file)
l2g_write(Local_to_global *l2g, FILE *fp)
{
L2g_block_info * binfo;
int i, j;
putc('[', fp);
binfo = l2g->blocks;
for (i = 0; i < l2g->num_blocks; ++i) {
if (binfo->key_block == NULL) {
/* Dense block */
for (j = 0; j < binfo->first_free; ++j) {
if (binfo->value_block[j] != 0) {
foutput_ulong((unsigned long) (binfo->start + j), fp);
foutput_ulong((unsigned long) (binfo->value_block[j]), fp);
}
}
} else {
/* Sparse block */
for (j = 0; j < binfo->first_free; ++j) {
if (binfo->value_block[j] != 0) {
foutput_ulong((unsigned long) (binfo->key_block[j]), fp);
foutput_ulong((unsigned long) (binfo->value_block[j]), fp);
}
}
}
binfo++;
}
fputs(" ]", fp);
}
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