Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
piece table data structure implemented using red-black tree.
@eu-ge-ne/text-buf
piece table
data structure implemented using red-black tree
.
In computing, a piece table is a data structure typically used to represent a text document while it is edited in a text editor. Initially a reference (or 'span') to the whole of the original file is created, which represents the as yet unchanged file. Subsequent inserts and deletes replace a span by combinations of one, two, or three references to sections of either the original document or to a buffer holding inserted text.
— Crowley, Charles (10 June 1998). "Data Structures for Text Sequences - 6.4 The piece table method"
Installation
Deno
deno add jsr:@eu-ge-ne/text-buf
Node.js
# pnpm pnpm i jsr:@eu-ge-ne/text-buf # yarn yarn add jsr:@eu-ge-ne/text-buf # npm npx jsr add @eu-ge-ne/text-buf
Bun
bunx jsr add @eu-ge-ne/text-buf
Examples
import { assertEquals } from "jsr:@std/assert"; import { TextBuf } from "jsr:@eu-ge-ne/text-buf"; const buf = new TextBuf(); assertEquals(buf.count, 0); assertEquals(buf.line_count, 0); assertEquals(buf.read(0), ""); buf.write(0, "Lorem"); assertEquals(buf.count, 5); assertEquals(buf.line_count, 1); assertEquals(buf.read(0), "Lorem"); buf.write(5, "ipsum"); assertEquals(buf.count, 10); assertEquals(buf.line_count, 1); assertEquals(buf.read(0), "Loremipsum"); buf.write(5, "\n"); buf.write(11, "\n"); assertEquals(buf.count, 12); assertEquals(buf.line_count, 3); assertEquals(buf.read(0), "Lorem\nipsum\n"); assertEquals(buf.read([0, 0], [1, 0]), "Lorem\n"); assertEquals(buf.read([1, 0], [2, 0]), "ipsum\n"); assertEquals(buf.read([2, 0], [3, 0]), ""); buf.delete(0, 6); buf.delete(5, 6); assertEquals(buf.count, 5); assertEquals(buf.line_count, 1); assertEquals(buf.read(0), "ipsum"); assertEquals(buf.read([0, 0], [1, 0]), "ipsum");
API
TextBuf()
Creates instances of TextBuf
interpreting text characters as
UTF-16 code units
. Visit
MDN
for more details. Accepts optional initial text.
Syntax
new TextBuf(text?: string)
TextBuf:count
Returns number of characters in the buffer.
Syntax
get count(): number
Example
import { assertEquals } from "jsr:@std/assert"; import { TextBuf } from "jsr:@eu-ge-ne/text-buf"; const buf = new TextBuf("Lorem ipsum"); assertEquals(buf.count, 11);
TextBuf:line_count
Returns number of lines in the buffer.
Syntax
get line_count(): number
Example
import { assertEquals } from "jsr:@std/assert"; import { TextBuf } from "jsr:@eu-ge-ne/text-buf"; const buf = new TextBuf("Lorem\nipsum\ndolor\nsit\namet"); assertEquals(buf.line_count, 5);
TextBuf.proto.read()
Returns text in the buffer's section, specified by start (inclusive) and end (exclusive) positions.
Syntax
read(start: Position, end?: Position): string
Example
import { assertEquals } from "jsr:@std/assert"; import { TextBuf } from "jsr:@eu-ge-ne/text-buf"; const buf = new TextBuf("Lorem\nipsum"); assertEquals(buf.read(0), "Lorem\nipsum"); assertEquals(buf.read(6), "ipsum"); assertEquals(buf.read([0, 0], [1, 0]), "Lorem\n"); assertEquals(buf.read([1, 0], [2, 0]), "ipsum");
TextBuf.proto.write()
Inserts text into the buffer at the specified position.
Syntax
write(position: Position, text: string): void
Example
import { assertEquals } from "jsr:@std/assert"; import { TextBuf } from "jsr:@eu-ge-ne/text-buf"; const buf = new TextBuf(); buf.write(0, "Lorem"); buf.write([0, 5], " ipsum"); assertEquals(buf.read(0), "Lorem ipsum");
TextBuf.proto.delete()
Removes characters in the buffer's section, specified by start (inclusive) and end (exclusive) positions.
Syntax
delete(start: Position, end?: Position): void
Example
import { assertEquals } from "jsr:@std/assert"; import { TextBuf } from "jsr:@eu-ge-ne/text-buf"; const buf = new TextBuf("Lorem ipsum"); buf.delete(5, 11); assertEquals(buf.read(0), "Lorem");
Benchmarks
Create
CPU | Apple M4 Pro Runtime | Deno 2.4.0 (aarch64-apple-darwin) file:///Users/eug/Dev/github.com/eu-ge-ne/text-buf/bench/create.bench.ts | benchmark | time/iter (avg) | iter/s | (min … max) | p75 | p99 | p995 | | -------------------- | --------------- | ------------- | --------------------- | -------- | -------- | -------- | group Create | Creating a TextBuf | 1.8 ms | 571.1 | ( 1.6 ms … 2.4 ms) | 1.7 ms | 2.3 ms | 2.3 ms | | Creating a string | 1.6 ms | 633.5 | ( 1.5 ms … 1.9 ms) | 1.6 ms | 1.9 ms | 1.9 ms | summary Creating a TextBuf 1.11x slower than Creating a string
Line
CPU | Apple M4 Pro Runtime | Deno 2.4.0 (aarch64-apple-darwin) file:///Users/eug/Dev/github.com/eu-ge-ne/text-buf/bench/line.bench.ts | benchmark | time/iter (avg) | iter/s | (min … max) | p75 | p99 | p995 | | ------------------------------- | --------------- | ------------- | --------------------- | -------- | -------- | -------- | group Line | Accessing a line in a TextBuf | 61.7 µs | 16,220 | ( 54.6 µs … 164.2 µs) | 62.6 µs | 89.8 µs | 96.2 µs | | Accessing a line in a string | 27.3 ms | 36.7 | ( 26.2 ms … 29.5 ms) | 27.8 ms | 29.5 ms | 29.5 ms | summary Accessing a line in a TextBuf 442.10x faster than Accessing a line in a string
Write
CPU | Apple M4 Pro Runtime | Deno 2.4.0 (aarch64-apple-darwin) file:///Users/eug/Dev/github.com/eu-ge-ne/text-buf/bench/write.bench.ts | benchmark | time/iter (avg) | iter/s | (min … max) | p75 | p99 | p995 | | -------------------------- | --------------- | ------------- | --------------------- | -------- | -------- | -------- | group Append | Appending into a TextBuf | 17.1 ms | 58.5 | ( 16.2 ms … 20.9 ms) | 17.2 ms | 20.9 ms | 20.9 ms | | Appending into a string | 5.9 ms | 169.6 | ( 5.5 ms … 6.5 ms) | 5.9 ms | 6.5 ms | 6.5 ms | summary Appending into a TextBuf 2.90x slower than Appending into a string group Insert | Inserting into a TextBuf | 65.0 ms | 15.4 | ( 60.5 ms … 71.2 ms) | 67.9 ms | 71.2 ms | 71.2 ms | | Inserting into a string | 1.3 s | 0.8 | ( 1.1 s … 1.4 s) | 1.3 s | 1.4 s | 1.4 s | summary Inserting into a TextBuf 19.45x faster than Inserting into a string
Delete
CPU | Apple M4 Pro Runtime | Deno 2.4.0 (aarch64-apple-darwin) file:///Users/eug/Dev/github.com/eu-ge-ne/text-buf/bench/delete.bench.ts | benchmark | time/iter (avg) | iter/s | (min … max) | p75 | p99 | p995 | | ------------------------- | --------------- | ------------- | --------------------- | -------- | -------- | -------- | group Trim | Trimming a TextBuf | 2.2 ms | 447.4 | ( 1.8 ms … 4.9 ms) | 2.3 ms | 3.0 ms | 3.0 ms | | Trimming a string | 261.6 µs | 3,823 | (230.6 µs … 593.6 µs) | 265.9 µs | 486.6 µs | 504.7 µs | summary Trimming a TextBuf 8.54x slower than Trimming a string group Delete | Deleting from a TextBuf | 5.4 ms | 184.1 | ( 4.8 ms … 6.3 ms) | 5.6 ms | 6.0 ms | 6.3 ms | | Deleting from a string | 120.7 ms | 8.3 | (120.5 ms … 120.9 ms) | 120.8 ms | 120.9 ms | 120.9 ms | summary Deleting from a TextBuf 22.22x faster than Deleting from a string
License
Add Package
deno add jsr:@eu-ge-ne/text-buf
Import symbol
import * as text_buf from "@eu-ge-ne/text-buf";
Import directly with a jsr specifier
import * as text_buf from "jsr:@eu-ge-ne/text-buf";
Add Package
pnpm i jsr:@eu-ge-ne/text-buf
pnpm dlx jsr add @eu-ge-ne/text-buf
Import symbol
import * as text_buf from "@eu-ge-ne/text-buf";
Add Package
yarn add jsr:@eu-ge-ne/text-buf
yarn dlx jsr add @eu-ge-ne/text-buf
Import symbol
import * as text_buf from "@eu-ge-ne/text-buf";
Add Package
vlt install jsr:@eu-ge-ne/text-buf
Import symbol
import * as text_buf from "@eu-ge-ne/text-buf";
Add Package
npx jsr add @eu-ge-ne/text-buf
Import symbol
import * as text_buf from "@eu-ge-ne/text-buf";
Add Package
bunx jsr add @eu-ge-ne/text-buf
Import symbol
import * as text_buf from "@eu-ge-ne/text-buf";