summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEkaitz Zarraga <ekaitz@elenq.tech>2025-08-22 00:35:21 +0200
committerEkaitz Zarraga <ekaitz@elenq.tech>2025-08-22 00:37:32 +0200
commitebb4cc5b97b8565ceffa0d48301f8af9e6b884df (patch)
treea0e68c4b7f72ea36abc2f27c0784e83e8b8da832
parentb04cbe08e23f63bc02c659b69668349fce240f9e (diff)
piece-table: Take original buffer from outside
-rw-r--r--src/piece-table-internals.h12
-rw-r--r--src/piece-table.c60
-rw-r--r--tests/piece-table-delete.c9
-rw-r--r--tests/piece-table-insert.c3
-rw-r--r--tests/piece-table-internals.c8
5 files changed, 37 insertions, 55 deletions
diff --git a/src/piece-table-internals.h b/src/piece-table-internals.h
index 75f00e1..b470bdb 100644
--- a/src/piece-table-internals.h
+++ b/src/piece-table-internals.h
@@ -20,9 +20,17 @@
#include "text-buffer.h"
+typedef enum
+ {
+ PIECE_SENTINEL,
+ PIECE_ORIG,
+ PIECE_ADD
+ }
+piece_type;
+
typedef struct _piece
{
- text_buffer *buffer;
+ piece_type type;
size_t start;
size_t length;
struct _piece *next;
@@ -41,7 +49,7 @@ piece_buffer;
typedef struct _piece_table
{
- text_buffer orig;
+ char *orig;
text_buffer add;
piece_buffer *pieces;
piece *sentinel;
diff --git a/src/piece-table.c b/src/piece-table.c
index 24e3671..070d265 100644
--- a/src/piece-table.c
+++ b/src/piece-table.c
@@ -91,7 +91,6 @@ piece_table_piece_new (piece_table *pt)
pt->empty = pt->empty->next;
return p;
}
- /* TODO: Resize if needed */
return piece_buffer_bump (pt->pieces);
}
@@ -102,7 +101,7 @@ piece_table_piece_split (piece_table *pt, piece *p, size_t pos)
/* Returns the first piece */
piece *second;
assert (pos < p->length);
- assert (p->buffer != NULL); /* Not a sentinel piece */
+ assert (p->type != PIECE_SENTINEL); /* Not a sentinel piece */
assert (p->length != 0); /* Not an empty piece (they should not exist) */
if ( pos == 0 )
{
@@ -116,7 +115,7 @@ piece_table_piece_split (piece_table *pt, piece *p, size_t pos)
p->next = second;
second->prev = p;
second->start = p->start + pos;
- second->buffer = p->buffer;
+ second->type = p->type;
return p;
}
@@ -165,7 +164,7 @@ piece_table_insert (piece_table *pt, size_t pos, char *in, size_t len)
assert ( pos <= pt->length );
assert ( len > 0 );
- for (i = 0; i<len; i++)
+ for (i=0; i<len; i++)
{
text_buffer_append (&pt->add, in[i]);
}
@@ -202,7 +201,7 @@ piece_table_insert (piece_table *pt, size_t pos, char *in, size_t len)
* Add in the end of the buffer, and the end of the piece: enlarge
*/
if ( pt->add.used != 0 &&
- start->buffer == &pt->add &&
+ start->type == PIECE_ADD &&
pt->cached_offset + start->length == pos &&
pt->add.used == start->start + start->length + len ) {
pt->length += len;
@@ -213,7 +212,7 @@ piece_table_insert (piece_table *pt, size_t pos, char *in, size_t len)
/* Make a new piece and insert it */
new = piece_table_piece_new (pt);
- new->buffer = &pt->add;
+ new->type = PIECE_ADD;
new->start = pt->add.used - len;
new->length = len;
@@ -284,8 +283,7 @@ piece_table_create_from_str (char *orig, size_t size)
pt->length = size;
/* Original buffer */
- text_buffer_init (&pt->orig);
- text_buffer_fill (&pt->orig, orig, size);
+ pt->orig = orig;
/* Add buffer */
text_buffer_init (&pt->add);
@@ -294,7 +292,7 @@ piece_table_create_from_str (char *orig, size_t size)
pt->sentinel = piece_buffer_bump (pt->pieces);
original = piece_buffer_bump (pt->pieces);
- original->buffer = &pt->orig;
+ original->type = PIECE_ORIG;
original->start = 0;
original->length = pt->length;
original->next = pt->sentinel;
@@ -317,7 +315,6 @@ piece_table_create (char *orig, size_t size)
void
piece_table_destroy (piece_table *pt)
{
- text_buffer_clear (&pt->orig);
text_buffer_clear (&pt->add);
piece_buffer_destroy (pt->pieces);
free (pt);
@@ -328,8 +325,17 @@ piece_table_index (piece_table *pt, size_t pos)
{
assert (pos < pt->length);
piece_table_piece_find (pt, pos);
- return text_buffer_index (pt->cached->buffer,
- pt->cached->start + pos - pt->cached_offset);
+ switch (pt->cached->type)
+ {
+ case PIECE_ORIG:
+ return pt->orig[pt->cached->start + pos - pt->cached_offset];
+ case PIECE_ADD:
+ return text_buffer_index (&pt->add,
+ pt->cached->start + pos - pt->cached_offset);
+ default:
+ assert (0 && "UNREACHABLE: indexing the sentinel piece");
+ break;
+ }
}
void
@@ -348,33 +354,3 @@ piece_table_length (piece_table *pt)
{
return pt->length;
}
-
-void
-piece_table_optimize (piece_table *pt)
-{
- piece *p;
- char *buff = malloc (sizeof (*buff) * pt->length + 1); /*TODO remove +1*/
- piece_table_to_string (pt, buff, pt->length);
- text_buffer_fill (&pt->orig, buff, pt->length);
- free (buff);
- text_buffer_clear (&pt->add);
- text_buffer_init (&pt->add);
-
- piece_buffer_empty (pt->pieces);
-
- pt->sentinel = piece_buffer_bump (pt->pieces);
- p = piece_buffer_bump (pt->pieces);
- pt->empty = NULL;
-
- p->next = pt->sentinel;
- p->prev = pt->sentinel;
- pt->sentinel->prev = p;
- pt->sentinel->next = p;
-
- p->start = 0;
- p->length = pt->length;
- p->buffer = &pt->orig;
-
- pt->cached_offset = 0;
- pt->cached = p;
-}
diff --git a/tests/piece-table-delete.c b/tests/piece-table-delete.c
index 4d9f1dd..835cd92 100644
--- a/tests/piece-table-delete.c
+++ b/tests/piece-table-delete.c
@@ -6,27 +6,28 @@
int
main ()
{
- piece_table *pt = piece_table_create_from_str ("0123456789", 10);
+ char orig[] = "0123456789";
char tmp[100];
+ piece_table *pt = piece_table_create_from_str (orig, 10);
piece_table_delete (pt, 0, 10);
piece_table_to_string (pt, tmp, 99);
assert (0 == strcmp (tmp, ""));
piece_table_destroy (pt);
- pt = piece_table_create_from_str ("0123456789", 10);
+ pt = piece_table_create_from_str (orig, 10);
piece_table_delete (pt, 0, 1);
piece_table_to_string (pt, tmp, 99);
assert (0 == strcmp (tmp, "123456789"));
piece_table_destroy (pt);
- pt = piece_table_create_from_str ("0123456789", 10);
+ pt = piece_table_create_from_str (orig, 10);
piece_table_delete (pt, 9, 1);
piece_table_to_string (pt, tmp, 99);
assert (0 == strcmp (tmp, "012345678"));
piece_table_destroy (pt);
- pt = piece_table_create_from_str ("0123456789", 10);
+ pt = piece_table_create_from_str (orig, 10);
piece_table_delete (pt, 7, 1);
piece_table_delete (pt, 0, 1);
piece_table_to_string (pt, tmp, 99);
diff --git a/tests/piece-table-insert.c b/tests/piece-table-insert.c
index 7604455..c49f7ba 100644
--- a/tests/piece-table-insert.c
+++ b/tests/piece-table-insert.c
@@ -6,8 +6,9 @@
int
main()
{
- piece_table *pt = piece_table_create_from_str ("0123456789", 10);
+ char orig[] = "0123456789";
char tmp[100];
+ piece_table *pt = piece_table_create_from_str (orig, 10);
piece_table_insert (pt, 10, "abcdefgh", 8);
piece_table_to_string (pt, tmp, 99);
diff --git a/tests/piece-table-internals.c b/tests/piece-table-internals.c
index 6cf5014..c89bfd6 100644
--- a/tests/piece-table-internals.c
+++ b/tests/piece-table-internals.c
@@ -17,9 +17,10 @@ count_pieces (piece_table *pt)
int
main ()
{
+ char orig[] = "0123456789";
char tmp[100];
size_t expected_count;
- piece_table *pt = piece_table_create_from_str ("0123456789", 10);
+ piece_table *pt = piece_table_create_from_str (orig, 10);
/** Inserting **/
/* Should add pieces... */
expected_count = 1;
@@ -51,11 +52,6 @@ main ()
piece_table_to_string (pt, tmp, 99);
assert (0 == strcmp (tmp, "abchabcde"));
- /** Optimize **/
- piece_table_optimize (pt);
- expected_count = 1;
- assert (count_pieces (pt) == expected_count);
-
/** Result **/
piece_table_to_string (pt, tmp, 99);
assert (0 == strcmp (tmp, "abchabcde"));