Redo gtables to prevent reduce number of mallocs and frees.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3024 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas 2000-10-06 08:59:58 +00:00
parent cc40000313
commit 2bba3b8d26
6 changed files with 89 additions and 133 deletions

View File

@ -52,25 +52,24 @@ gnc_cellblock_new (int rows, int cols)
/* =================================================== */
static gpointer
gnc_cellblock_cell_new (gpointer user_data)
static void
gnc_cellblock_cell_construct (gpointer _cb_cell, gpointer user_data)
{
CellBlockCell *cb_cell;
cb_cell = g_new0(CellBlockCell, 1);
CellBlockCell *cb_cell = _cb_cell;
cb_cell->cell = NULL;
cb_cell->cell_type = -1;
cb_cell->sample_text = NULL;
cb_cell->alignment = CELL_ALIGN_LEFT;
cb_cell->expandable = FALSE;
cb_cell->span = FALSE;
return cb_cell;
}
/* =================================================== */
static void
gnc_cellblock_cell_free (gpointer _cb_cell, gpointer user_data)
gnc_cellblock_cell_destroy (gpointer _cb_cell, gpointer user_data)
{
CellBlockCell *cb_cell = _cb_cell;
@ -79,10 +78,6 @@ gnc_cellblock_cell_free (gpointer _cb_cell, gpointer user_data)
g_free(cb_cell->sample_text);
cb_cell->sample_text = NULL;
g_free(cb_cell);
return;
}
/* =================================================== */
@ -100,8 +95,9 @@ gnc_cellblock_init (CellBlock *cellblock, int rows, int cols)
cellblock->num_cols = cols;
/* malloc new cell table */
cellblock->cb_cells = g_table_new (gnc_cellblock_cell_new,
gnc_cellblock_cell_free, NULL);
cellblock->cb_cells = g_table_new (sizeof (CellBlockCell),
gnc_cellblock_cell_construct,
gnc_cellblock_cell_destroy, NULL);
g_table_resize (cellblock->cb_cells, rows, cols);
}

View File

@ -1895,7 +1895,7 @@ gnucash_sheet_set_scroll_region (GnucashSheet *sheet)
}
static void
gnucash_sheet_block_free (gpointer _block, gpointer user_data)
gnucash_sheet_block_destroy (gpointer _block, gpointer user_data)
{
SheetBlock *block = _block;
@ -1906,18 +1906,14 @@ gnucash_sheet_block_free (gpointer _block, gpointer user_data)
gnucash_style_unref (block->style);
block->style = NULL;
}
g_free (block);
}
static gpointer
gnucash_sheet_block_new (gpointer user_data)
static void
gnucash_sheet_block_construct (gpointer _block, gpointer user_data)
{
SheetBlock *block;
SheetBlock *block = _block;
block = g_new0 (SheetBlock, 1);
return block;
block->style = NULL;
}
static void
@ -2122,8 +2118,9 @@ gnucash_sheet_init (GnucashSheet *sheet)
sheet->height = 0;
sheet->smooth_scroll = TRUE;
sheet->blocks = g_table_new(gnucash_sheet_block_new,
gnucash_sheet_block_free, NULL);
sheet->blocks = g_table_new(sizeof (SheetBlock),
gnucash_sheet_block_construct,
gnucash_sheet_block_destroy, NULL);
}

View File

@ -66,24 +66,15 @@ style_get_key (SheetBlockStyle *style)
}
static gpointer
cell_dimensions_new (gpointer user_data)
static void
cell_dimensions_construct (gpointer _cd, gpointer user_data)
{
CellDimensions *cd;
cd = g_new0 (CellDimensions, 1);
CellDimensions *cd = _cd;
cd->pixel_width = -1;
cd->can_span_over = TRUE;
return cd;
}
static void
cell_dimensions_free (gpointer cd, gpointer user_data)
{
g_free(cd);
}
static BlockDimensions *
style_dimensions_new (SheetBlockStyle *style)
@ -95,8 +86,9 @@ style_dimensions_new (SheetBlockStyle *style)
dimensions->nrows = style->nrows;
dimensions->ncols = style->ncols;
dimensions->cell_dimensions = g_table_new (cell_dimensions_new,
cell_dimensions_free, NULL);
dimensions->cell_dimensions = g_table_new (sizeof (CellDimensions),
cell_dimensions_construct,
NULL, NULL);
g_table_resize (dimensions->cell_dimensions,
style->nrows, style->ncols);
@ -627,25 +619,23 @@ gnucash_style_get_cell_style (SheetBlockStyle *style, int row, int col)
return g_table_index (style->cell_styles, row, col);
}
static gpointer
cell_style_new (gpointer user_data)
static void
cell_style_construct (gpointer _cs, gpointer user_data)
{
CellStyle *cs;
CellStyle *cs = _cs;
cs = g_new0 (CellStyle, 1);
return cs;
cs->label = NULL;
cs->active_bg_color = NULL;
cs->inactive_bg_color = NULL;
}
static void
cell_style_free (gpointer _cs, gpointer user_data)
cell_style_destroy (gpointer _cs, gpointer user_data)
{
CellStyle *cs = _cs;
g_free(cs->label);
cs->label = NULL;
g_free(cs);
}
static SheetBlockStyle *
@ -669,8 +659,9 @@ gnucash_sheet_style_new (GnucashSheet *sheet, CellBlock *cursor,
style->nrows = cursor->num_rows;
style->ncols = cursor->num_cols;
style->cell_styles = g_table_new (cell_style_new,
cell_style_free, NULL);
style->cell_styles = g_table_new (sizeof (CellStyle),
cell_style_construct,
cell_style_destroy, NULL);
g_table_resize (style->cell_styles, style->nrows, style->ncols);
gnucash_sheet_style_recompile(style, sr, cursor_type);

View File

@ -25,36 +25,38 @@
struct GTable
{
GPtrArray *array;
GArray *array;
guint entry_size;
int rows;
int cols;
g_table_allocator allocator;
g_table_deallocator deallocator;
g_table_entry_constructor constructor;
g_table_entry_destroyer destroyer;
gpointer user_data;
};
GTable *
g_table_new (g_table_allocator allocator,
g_table_deallocator deallocator,
g_table_new (guint entry_size,
g_table_entry_constructor constructor,
g_table_entry_destroyer destroyer,
gpointer user_data)
{
GTable *gtable;
g_assert (allocator);
g_assert (deallocator);
gtable = g_new(GTable, 1);
gtable->array = g_ptr_array_new();
gtable->array = g_array_new(FALSE, FALSE, entry_size);
gtable->entry_size = entry_size;
gtable->rows = 0;
gtable->cols = 0;
gtable->allocator = allocator;
gtable->deallocator = deallocator;
gtable->constructor = constructor;
gtable->destroyer = destroyer;
gtable->user_data = user_data;
@ -69,7 +71,7 @@ g_table_destroy (GTable *gtable)
g_table_resize (gtable, 0, 0);
g_ptr_array_free (gtable->array, FALSE);
g_array_free (gtable->array, TRUE);
gtable->array = NULL;
@ -90,9 +92,9 @@ g_table_index (GTable *gtable, int row, int col)
if (col >= gtable->cols)
return NULL;
index = (row * gtable->cols) + col;
index = ((row * gtable->cols) + col) * gtable->entry_size;
return gtable->array->pdata[index];
return &gtable->array->data[index];
}
void
@ -112,29 +114,35 @@ g_table_resize (GTable *gtable, int rows, int cols)
if (new_len == old_len)
return;
/* If shrinking, free extra cells */
if (new_len < old_len)
/* If shrinking, destroy extra cells */
if ((new_len < old_len) && gtable->destroyer)
{
gpointer *tcp;
gchar *entry;
guint i;
tcp = &gtable->array->pdata[new_len];
for (i = new_len; i < old_len; i++, tcp++)
gtable->deallocator(*tcp, gtable->user_data);
entry = &gtable->array->data[new_len * gtable->entry_size];
for (i = new_len; i < old_len; i++)
{
gtable->destroyer(entry, gtable->user_data);
entry += gtable->entry_size;
}
}
/* Change the size */
g_ptr_array_set_size(gtable->array, new_len);
g_array_set_size(gtable->array, new_len);
/* If expanding, create the new cells */
if (new_len > old_len)
/* If expanding, construct the new cells */
if ((new_len > old_len) && gtable->constructor)
{
gpointer *tcp;
gchar *entry;
guint i;
tcp = &gtable->array->pdata[old_len];
for (i = old_len; i < new_len; i++, tcp++)
*tcp = gtable->allocator(gtable->user_data);
entry = &gtable->array->data[old_len * gtable->entry_size];
for (i = old_len; i < new_len; i++)
{
gtable->constructor(entry, gtable->user_data);
entry += gtable->entry_size;
}
}
gtable->rows = rows;

View File

@ -31,15 +31,16 @@
typedef struct GTable GTable;
typedef gpointer (*g_table_allocator) (gpointer user_data);
typedef void (*g_table_deallocator) (gpointer entry, gpointer user_data);
typedef void (*g_table_entry_constructor) (gpointer entry, gpointer user_data);
typedef void (*g_table_entry_destroyer) (gpointer entry, gpointer user_data);
/* Create a new table with the given allocator and deallocator.
* Both functions must be given. They are used to populate the
* table and free extra members when resizing and destroying. */
GTable * g_table_new (g_table_allocator allocator,
g_table_deallocator deallocator,
/* Create a new table with the given entry constructor and destroyer.
* Both functions must be given. They are used to initialize the table
* entries and free unneeded memory when resizing and destroying. */
GTable * g_table_new (guint entry_size,
g_table_entry_constructor constructor,
g_table_entry_destroyer destroyer,
gpointer user_data);
/* Free the table and all associated table elements. */

View File

@ -41,30 +41,18 @@
#include "util.h"
/** Datatypes **********************************************************/
/* The generic TableCell is used for memory allocation purposes. */
typedef union _TableCell TableCell;
union _TableCell
{
VirtualCell virt_cell;
};
/** Static Globals *****************************************************/
/* This static indicates the debugging module that this .o belongs to. */
static short module = MOD_REGISTER;
static GMemChunk *cell_mem_chunk = NULL;
/** Prototypes *********************************************************/
static void gnc_table_init (Table * table);
static void gnc_table_free_data (Table * table);
static gpointer gnc_virtual_cell_new (gpointer user_data);
static void gnc_virtual_cell_construct (gpointer vcell, gpointer user_data);
static void gnc_virtual_location_init (VirtualLocation *vloc);
static void gnc_virtual_cell_free (gpointer tcell, gpointer user_data);
static void gnc_virtual_cell_destroy (gpointer vcell, gpointer user_data);
static void gnc_table_resize (Table * table, int virt_rows, int virt_cols);
@ -82,10 +70,6 @@ gnc_table_new (TableGetEntryHandler entry_handler,
g_assert (entry_handler != NULL);
/* Do this here for lower overhead. */
if (cell_mem_chunk == NULL)
cell_mem_chunk = g_mem_chunk_create(TableCell, 2048, G_ALLOC_AND_FREE);
table = g_new0(Table, 1);
table->entry_handler = entry_handler;
@ -97,8 +81,9 @@ gnc_table_new (TableGetEntryHandler entry_handler,
gnc_table_init (table);
table->virt_cells = g_table_new(gnc_virtual_cell_new,
gnc_virtual_cell_free, table);
table->virt_cells = g_table_new(sizeof (VirtualCell),
gnc_virtual_cell_construct,
gnc_virtual_cell_destroy, table);
return table;
}
@ -158,18 +143,11 @@ gnc_table_destroy (Table * table)
VirtualCell *
gnc_table_get_virtual_cell (Table *table, VirtualCellLocation vcell_loc)
{
TableCell *tcell;
if (table == NULL)
return NULL;
tcell = g_table_index (table->virt_cells,
vcell_loc.virt_row, vcell_loc.virt_col);
if (tcell == NULL)
return NULL;
return &tcell->virt_cell;
return g_table_index (table->virt_cells,
vcell_loc.virt_row, vcell_loc.virt_col);
}
/* ==================================================== */
@ -371,16 +349,11 @@ gnc_virtual_location_init (VirtualLocation *vloc)
/* ==================================================== */
static gpointer
gnc_virtual_cell_new (gpointer user_data)
static void
gnc_virtual_cell_construct (gpointer _vcell, gpointer user_data)
{
VirtualCell *vcell = _vcell;
Table *table = user_data;
TableCell *tcell;
VirtualCell *vcell;
tcell = g_chunk_new(TableCell, cell_mem_chunk);
vcell = &tcell->virt_cell;
vcell->cellblock = NULL;
@ -388,30 +361,20 @@ gnc_virtual_cell_new (gpointer user_data)
vcell->vcell_data = table->vcell_data_allocator();
else
vcell->vcell_data = NULL;
return tcell;
}
/* ==================================================== */
static void
gnc_virtual_cell_free (gpointer _tcell, gpointer user_data)
gnc_virtual_cell_destroy (gpointer _vcell, gpointer user_data)
{
VirtualCell *vcell = _vcell;
Table *table = user_data;
TableCell *tcell = _tcell;
VirtualCell *vcell;
if (tcell == NULL)
return;
vcell = &tcell->virt_cell;
if (vcell->vcell_data && table && table->vcell_data_deallocator)
table->vcell_data_deallocator (vcell->vcell_data);
vcell->vcell_data = NULL;
g_mem_chunk_free(cell_mem_chunk, tcell);
}
/* ==================================================== */