[vte] [ring] Remove GArray for rowcell allocation



commit 064822346af55ce36e0a7e82b38bf235e9fb394f
Author: Behdad Esfahbod <behdad behdad org>
Date:   Sat Sep 5 00:06:38 2009 -0400

    [ring] Remove GArray for rowcell allocation
    
    A very dumb allocator right now.  To be optimized.

 src/ring.c |  124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 src/ring.h |   47 ++++++++++++----------
 2 files changed, 140 insertions(+), 31 deletions(-)
---
diff --git a/src/ring.c b/src/ring.c
index 9285a26..03cd9eb 100644
--- a/src/ring.c
+++ b/src/ring.c
@@ -25,13 +25,54 @@
 #include "debug.h"
 #include "ring.h"
 
+/*
+ * vtecells: A row's cell array
+ */
+
+typedef struct _vtecells vtecells;
+struct _vtecells {
+	unsigned int alloc_size;
+	union {
+		vtecells *next;
+		vtecell cells[1];
+	} p;
+};
+
+static inline vtecells *
+vtecells_for_cells (vtecell *cells)
+{
+  return (vtecells *) (((char *) cells) - G_STRUCT_OFFSET (vtecells, p.cells));
+}
+
+static vtecell *
+_vte_cells_realloc (vtecell *cells, unsigned int len)
+{
+	vtecells *vcells = cells ? vtecells_for_cells (cells) : NULL;
+	unsigned int new_size = (1 << g_bit_storage (MAX (len, 80)));
+
+	vcells = g_realloc (vcells, sizeof (vtecells) + len * sizeof (vtecell));
+	vcells->alloc_size = new_size;
+
+	return vcells->p.cells;
+}
+
+static void
+_vte_cells_free (vtecell *cells)
+{
+	vtecells *vcells = vtecells_for_cells (cells);
+
+	g_free (vcells);
+}
+
+
+/*
+ * VteRowData: A row's data
+ */
+
 static VteRowData *
 _vte_row_data_init (VteRowData *row)
 {
-	if (row->_cells)
-		g_array_set_size (row->_cells, 0);
-	else
-		row->_cells = g_array_new(FALSE, TRUE, sizeof(vtecell));
+	row->len = 0;
 	row->soft_wrapped = 0;
 	return row;
 }
@@ -39,11 +80,76 @@ _vte_row_data_init (VteRowData *row)
 static void
 _vte_row_data_fini (VteRowData *row)
 {
-	if (row->_cells)
-		g_array_free(row->_cells, TRUE);
-	row->_cells = NULL;
+	if (row->cells)
+		_vte_cells_free (row->cells);
+	row->cells = NULL;
+}
+
+static void
+_vte_row_data_ensure (VteRowData *row, unsigned int len)
+{
+	if (row->len < len)
+		row->cells = _vte_cells_realloc (row->cells, len);
+}
+
+void
+_vte_row_data_insert (VteRowData *row, unsigned int col, const vtecell *cell)
+{
+	unsigned int i;
+
+	_vte_row_data_ensure (row, row->len + 1);
+
+	for (i = row->len; i > col; i--)
+		row->cells[i] = row->cells[i - 1];
+
+	row->cells[col] = *cell;
+	row->len++;
+}
+
+void _vte_row_data_append (VteRowData *row, const vtecell *cell)
+{
+	_vte_row_data_ensure (row, row->len + 1);
+	row->cells[row->len] = *cell;
+	row->len++;
+}
+
+void _vte_row_data_remove (VteRowData *row, unsigned int col)
+{
+	unsigned int i;
+
+	for (i = col + 1; i < row->len; i++)
+		row->cells[i - 1] = row->cells[i];
+
+	if (G_LIKELY (row->len))
+		row->len--;
+}
+
+void _vte_row_data_fill (VteRowData *row, const vtecell *cell, unsigned int len)
+{
+	if (row->len < len) {
+		unsigned int i = len - row->len;
+
+		_vte_row_data_ensure (row, len);
+
+		for (i = row->len; i < len; i++)
+			row->cells[i] = *cell;
+
+		row->len = len;
+	}
+}
+
+void _vte_row_data_shrink (VteRowData *row, unsigned int max_len)
+{
+	if (max_len < row->len)
+		row->len = max_len;
 }
 
+
+
+/*
+ * VteRing: A buffer ring
+ */
+
 static void
 _vte_ring_swap (VteRing *ring, unsigned int to, unsigned int from)
 {
@@ -68,10 +174,8 @@ _vte_ring_validate (VteRing * ring)
 			ring->delta, ring->length, ring->max);
 	g_assert(ring->length <= ring->max);
 	max = ring->delta + ring->length;
-	for (i = ring->delta; i < max; i++) {
+	for (i = ring->delta; i < max; i++)
 		g_assert(_vte_ring_contains(ring, i));
-		g_assert(_vte_ring_index(ring, i)->_cells != NULL);
-	}
 }
 #else
 #define _vte_ring_validate(ring) G_STMT_START {} G_STMT_END
diff --git a/src/ring.h b/src/ring.h
index f8e2665..ac79165 100644
--- a/src/ring.h
+++ b/src/ring.h
@@ -38,6 +38,11 @@ G_BEGIN_DECLS
 
 #define FRAGMENT			-2
 
+
+/*
+ * vtecellattr: A single cell style attributes
+ */
+
 typedef struct _vtecellattr {
 	guint32 columns: 4;	/* Number of visible columns
 				   (as determined by g_unicode_iswide(c)).
@@ -65,6 +70,10 @@ typedef struct _vtecellattr {
 } vtecellattr;
 
 
+/*
+ * vtecell: A single cell's data
+ */
+
 typedef struct _vtecell {
 	vteunistr c;
 	vtecellattr attr;
@@ -90,45 +99,41 @@ static const vtecell basic_cell = {
 	}
 };
 
+
+/*
+ * VteRowData: A single row's data
+ */
+
 typedef struct _VteRowData {
-	GArray *_cells;
+	vtecell *cells;
+	unsigned int len;
 	guchar soft_wrapped: 1;
 } VteRowData;
 
 
 #define _vte_row_data_get(__row, __col)			((const vtecell *) _vte_row_data_get_writable (__row, __col))
-#define _vte_row_data_length(__row)			((__row)->_cells->len + 0)
-#define _vte_row_data_insert(__row, __pos, __cell)	g_array_insert_val ((__row)->_cells, __pos, *(__cell))
-#define _vte_row_data_append(__row, __cell)		g_array_append_val ((__row)->_cells, *(__cell))
-#define _vte_row_data_remove(__row, __col)		g_array_remove_index ((__row)->_cells, __col)
-#define _vte_row_data_fill(__row, __cell, __len)	G_STMT_START { \
-								int __i = (__len) - (__row)->_cells->len; \
-								while (__i-- > 0)  \
-									_vte_row_data_append (__row, __cell); \
-							} G_STMT_END
-
-#define _vte_row_data_shrink(__row, __max_len)		g_array_set_size ((__row)->_cells, MIN((__row)->_cells->len, (unsigned int)(__max_len)))
+#define _vte_row_data_length(__row)			((__row)->len + 0)
 
 static inline vtecell *
 _vte_row_data_get_writable (VteRowData *row, unsigned int col)
 {
-	if (G_UNLIKELY (row->_cells->len <= col))
+	if (G_UNLIKELY (row->len <= col))
 		return NULL;
 
-	return &g_array_index (row->_cells, vtecell, col);
+	return &row->cells[col];
 }
 
-#if 0
-const vtecell *_vte_row_data_get (VteRowData *row, unsigned int col);
-unsigned int _vte_row_data_length (VteRowData *row);
-void _vte_row_data_insert (VteRowData *row, int pos, const vtecell *cell);
+void _vte_row_data_insert (VteRowData *row, unsigned int col, const vtecell *cell);
 void _vte_row_data_append (VteRowData *row, const vtecell *cell);
 void _vte_row_data_remove (VteRowData *row, unsigned int col);
-void _vte_row_data_fill (VteRowData *row, const vtecell *cell, int len);
-void _vte_row_data_shrink (VteRowData *row, int max_len);
-#endif
+void _vte_row_data_fill (VteRowData *row, const vtecell *cell, unsigned int len);
+void _vte_row_data_shrink (VteRowData *row, unsigned int max_len);
 
 
+/*
+ * VteRing: A buffer ring
+ */
+
 typedef struct _VteRing VteRing;
 
 struct _VteRing {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]