Commit 37e24129 authored by Per Cederqvist's avatar Per Cederqvist
Browse files

(nr_constructs): New static variable, used to gather statistics.

	Changed all functions to set it where appropriate.
(nr_l2gs): Likewise.
(nr_l2gs_peak): Likewise.
(nr_destructs): Likewise.
(nr_clears): Likewise.
(nr_copies): Likewise.
(nr_joins): Likewise.
(nr_joined_blocks): Likewise.
(nr_blocks): Likewise.
(nr_blocks_peak): Likewise.
(nr_blocks_sparse): Likewise.
(nr_blocks_sparse_peak): Likewise.
(sparse_skip_cost): Likewise.
(nr_sparse_compactions): Likewise.
(nr_sparsifications): Likewise.
(l2g_destruct): Actually fill the destructed object with garbage
	data, unless NDEBUG is defined.
(l2g_read): New file format.
(put_ulong): New static function.
(l2g_write): New file format.
(dump_l2g_stats): New function.
parent 2ce9ead9
......@@ -66,6 +66,24 @@ struct l2g_block_info {
};
static long nr_constructs = 0;
static long nr_l2gs = 0;
static long nr_l2gs_peak = 0;
static long nr_destructs = 0;
static long nr_clears = 0;
static long nr_copies = 0;
static long nr_joins = 0;
static long nr_joined_blocks = 0;
static long nr_blocks = 0;
static long nr_blocks_peak = 0;
static long nr_blocks_sparse = 0;
static long nr_blocks_sparse_peak = 0;
static long sparse_skip_cost = 0;
static long nr_sparse_compactions = 0;
static long nr_sparsifications = 0;
/* ================================================================ */
/* ==== Static functions ==== */
/* ================================================================ */
......@@ -99,7 +117,10 @@ sparse_skip_deleted(const struct l2g_block_info *binfo,
int i)
{
while (i < binfo->first_free && binfo->value_block[i] == 0)
{
++sparse_skip_cost;
++i;
}
return i;
}
......@@ -155,6 +176,7 @@ sparse_compact(struct l2g_block_info *binfo)
binfo->first_free = to;
assert(binfo->first_free + binfo->zeroes == L2G_BLOCKSIZE);
++nr_sparse_compactions;
}
......@@ -184,16 +206,18 @@ add_block(Local_to_global *l2g)
binfo->first_free = 0;
binfo->zeroes = L2G_BLOCKSIZE;
#ifndef NDEBUG
binfo->start = (Local_text_no)0xdeadbeefUL;
binfo->start = 0xdeadbeef;
#endif
binfo->key_block = NULL;
binfo->value_block = smalloc(L2G_BLOCKSIZE * sizeof(Text_no));
#ifndef NDEBUG
for (i = 0; i < L2G_BLOCKSIZE; ++i)
binfo->value_block[i] = (Local_text_no)0xdeadbeefUL;
binfo->value_block[i] = 0xdeadbeef;
#endif
if (++nr_blocks > nr_blocks_peak)
nr_blocks_peak = nr_blocks;
return binfo;
}
......@@ -209,6 +233,10 @@ delete_block(Local_to_global *l2g,
{
assert(is_empty(binfo));
if (!is_dense(binfo))
--nr_blocks_sparse;
--nr_blocks;
/* Remove the blocks from the Block Info */
if (binfo->key_block != NULL)
sfree(binfo->key_block);
......@@ -233,6 +261,9 @@ make_sparse(struct l2g_block_info *binfo)
int i;
assert(is_dense(binfo));
if (++nr_blocks_sparse > nr_blocks_sparse_peak)
nr_blocks_sparse_peak = nr_blocks_sparse;
++nr_sparsifications;
/* Allocate the room for the key block. */
binfo->key_block = smalloc(L2G_BLOCKSIZE * sizeof(Local_text_no));
......@@ -393,9 +424,11 @@ join_range(Local_to_global *l2g,
else
sparse_compact(first);
++nr_joins;
next = first->first_free;
for (binfo = first + 1; binfo <= last; ++binfo)
{
++nr_joined_blocks;
for (i = 0; i < binfo->first_free; ++i)
if (binfo->value_block[i] != 0)
{
......@@ -404,7 +437,10 @@ join_range(Local_to_global *l2g,
next++;
}
if (!is_dense(binfo))
{
--nr_blocks_sparse;
sfree(binfo->key_block);
}
sfree(binfo->value_block);
}
......@@ -419,6 +455,7 @@ join_range(Local_to_global *l2g,
first->first_free = next;
first->zeroes = L2G_BLOCKSIZE - next;
nr_blocks -= last - first;
l2g->num_blocks -= last - first;
l2g->blocks = srealloc(l2g->blocks,
l2g->num_blocks * sizeof(struct l2g_block_info));
......@@ -486,21 +523,20 @@ join_blocks(Local_to_global *l2g,
/* ================================================================ */
/*
* Remove all memory associated with the structure.
*/
void
l2g_destruct(Local_to_global *l2g)
{
l2g_clear(l2g);
++nr_destructs;
--nr_l2gs;
#ifndef NDEBUG
l2g->num_blocks = 0xdeadbeef;
l2g->first_unused = 0xdeadbeef;
l2g->blocks = (void*)0xdeadbeef;
#endif
}
/*
* Initialize an empty piece of memory to be a Local to global structure.
*/
void
l2g_init(Local_to_global *l2g)
{
......@@ -508,13 +544,12 @@ l2g_init(Local_to_global *l2g)
l2g->num_blocks = 0;
l2g->first_unused = 1;
l2g->blocks = NULL;
++nr_constructs;
if (++nr_l2gs > nr_l2gs_peak)
nr_l2gs_peak = nr_l2gs;
}
/*
* Make L2G into an empty structure, ready to put the first data into it.
*/
void
l2g_clear(Local_to_global *l2g)
{
......@@ -526,11 +561,15 @@ l2g_clear(Local_to_global *l2g)
for (i = 0; i < l2g->num_blocks; ++i)
{
if (binfo->key_block != NULL)
{
--nr_blocks_sparse;
sfree(binfo->key_block);
}
sfree(binfo->value_block);
binfo++;
}
nr_blocks -= l2g->num_blocks;
/* Free the block pointers. */
l2g->num_blocks = 0;
......@@ -540,6 +579,7 @@ l2g_clear(Local_to_global *l2g)
sfree(l2g->blocks);
l2g->blocks = NULL;
}
++nr_clears;
}
......@@ -562,14 +602,10 @@ l2g_copy(Local_to_global *dest, const Local_to_global *src)
l2g_append(dest, key_value(binfo, i), binfo->value_block[i]);
assert(src->first_unused >= dest->first_unused);
dest->first_unused = src->first_unused;
++nr_copies;
}
/*
* Append the pair LNO-TNO. LNO has to be bigger than the last local
* number in the structure.
*/
typedef Local_text_no Local_text_no_iter;
void
......@@ -825,7 +861,7 @@ Success
l2g_read(FILE *fp, Local_to_global *l2g)
{
int c;
Local_text_no lno;
Local_text_no lno = 0;
Text_no tno;
Local_text_no first_unused;
......@@ -835,59 +871,125 @@ l2g_read(FILE *fp, Local_to_global *l2g)
fskipwhite(fp);
if ( (c = getc(fp)) == EOF || c != '[')
{
log("l2g_read() failed at pos %lu.\n", (unsigned long) ftell(fp));
log("l2g_read() failed to find ``['' marker at pos %lu.\n",
(unsigned long) ftell(fp));
return FAILURE;
}
fskipwhite(fp);
first_unused = fparse_long(fp);
/* Read pairs of numbers until the EOL (end-of-l2g :-) ) marker is read. */
/* Read numbers until the EOL (end-of-l2g :-) ) marker is read. */
while (1)
{
fskipwhite(fp);
if ((c = getc(fp)) == ']')
break;
if (c == EOF)
if ((c = getc(fp)) == EOF)
{
log("l2g_read(): unexpected EOF at pos %lu.\n",
(unsigned long) ftell(fp));
return FAILURE;
}
ungetc(c, fp);
lno = (Local_text_no) fparse_long(fp);
tno = (Text_no) fparse_long(fp);
l2g_append(l2g, lno, tno);
switch (c)
{
case ' ':
lno = fparse_long(fp);
if (lno == 0)
{
log("l2g_read(): got local number 0 at pos %lu.\n",
(unsigned long) ftell(fp));
return FAILURE;
}
break;
case ',':
if (lno == 0)
{
log("l2g_read(): missing local number at pos %lu.\n",
(unsigned long)ftell(fp));
return FAILURE;
}
++lno;
/*FALLTHROUGH*/
case ':':
if (lno == 0)
{
log("l2g_read(): missing local number at pos %lu.\n",
(unsigned long)ftell(fp));
return FAILURE;
}
tno = fparse_long(fp);
l2g_append(l2g, lno, tno);
break;
case ']':
assert(first_unused >= l2g->first_unused);
l2g->first_unused = first_unused;
return OK;
default:
log("l2g_read(): unexpected character ``%c'' at pos %lu.\n",
c, (unsigned long) ftell(fp));
return FAILURE;
}
}
assert(first_unused >= l2g->first_unused);
l2g->first_unused = first_unused;
return OK;
}
/* Write the unsigned long value ``l'' to ``fp''. */
static void
put_ulong(unsigned long l,
FILE *fp)
{
static char buf[sizeof(unsigned long) * 3 + 1];
char *cp;
if (l < 10)
putc("0123456789"[l], fp);
else
{
cp = buf + sizeof(buf);
while (l > 0)
{
*--cp = (l % 10) + '0';
l /= 10;
}
fwrite(cp, buf + sizeof(buf) - cp, 1, fp);
}
}
void
l2g_write(FILE *fp, const Local_to_global *l2g)
{
const struct l2g_block_info *binfo;
int ix;
Local_text_no key;
Text_no val;
Local_text_no current = 0;
putc('[', fp);
foutput_ulong((unsigned long) l2g->first_unused, fp);
put_ulong(l2g->first_unused, fp);
for (binfo = l2g->blocks; binfo < l2g->blocks + l2g->num_blocks; ++binfo)
for (ix = 0; ix < binfo->first_free; ++ix)
if (binfo->value_block[ix] != 0)
if ((val = binfo->value_block[ix]) != 0)
{
foutput_ulong((unsigned long) key_value(binfo, ix), fp);
foutput_ulong((unsigned long) binfo->value_block[ix], fp);
key = key_value(binfo, ix);
if (key > current + 3 || current == 0)
{
putc(' ', fp);
put_ulong(key, fp);
putc(':', fp);
put_ulong(val, fp);
current = key;
}
else
{
while (++current < key)
{
putc(',', fp);
putc('0', fp);
}
putc(',', fp);
put_ulong(val, fp);
}
}
fputs(" ]", fp);
putc(']', fp);
}
......@@ -999,3 +1101,26 @@ l2gi_end(const L2g_iterator *l2gi)
return l2gi->endval;
}
/* ---------- */
extern void
dump_l2g_stats(FILE *file)
{
fprintf(file, "---%s:\n\tExisting l2gs: %ld\n",
__FILE__, nr_l2gs);
fprintf(file, "\tExisting sparse blocks: %ld\n", nr_blocks_sparse);
fprintf(file, "\tExisting blocks (total): %ld\n", nr_blocks);
fprintf(file, "\tPeak l2gs: %ld\n", nr_l2gs_peak);
fprintf(file, "\tPeak sparse blocks: %ld\n", nr_blocks_sparse_peak);
fprintf(file, "\tPeak blocks (total): %ld\n", nr_blocks_peak);
fprintf(file, "\tctor calls: %ld\n", nr_constructs);
fprintf(file, "\tdtor calls: %ld\n", nr_destructs);
fprintf(file, "\tclear calls: %ld\n", nr_clears);
fprintf(file, "\tcopy calls: %ld\n", nr_copies);
fprintf(file, "\tjoin operations: %ld\n", nr_joins);
fprintf(file, "\tjoined blocks: %ld\n", nr_joined_blocks);
fprintf(file, "\tsparse skip cost: %ld\n", sparse_skip_cost);
fprintf(file, "\tsparse compactions: %ld\n", nr_sparse_compactions);
fprintf(file, "\tsparsifications: %ld\n", nr_sparsifications);
}
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