fix: apply fast string comrpession

This commit is contained in:
TrèsAbhi committed 2024-02-05 18:33:17 -06:00
1 parent 2de077a3ab
commit 708bcab2f3
1 file changed
+41 -11
+41 -11
View File
@@ -108,7 +108,7 @@ export class BkonReadStream extends ReadStream {
fastStringFormat: FastStringFormat, fastStringFormat: FastStringFormat,
stringTable: Record<number, string>, stringTable: Record<number, string>,
): BkonValue { ): BkonValue {
const type = this.uint8(); const type = this.uint8() as ValueType;
switch (type) { switch (type) {
case ValueType.Null: case ValueType.Null:
@@ -193,17 +193,25 @@ export class BkonReadStream extends ReadStream {
export class BkonWriteStream extends WriteStream { export class BkonWriteStream extends WriteStream {
bkon(object: BkonValue) { bkon(object: BkonValue) {
this.magic(); this.magic();
const stringTable = this.header(object); const header = this.header(object);
this.body(object, stringTable); this.body(header.fastStringFormat, object, header.stringTable);
return this; return this;
} }
body(object: BkonValue, stringTable: Map<string, number>) { body(
this.value(object, stringTable); fastStringFormat: FastStringFormat,
object: BkonValue,
stringTable: Map<string, number>,
) {
this.value(fastStringFormat, object, stringTable);
return this; return this;
} }
value(object: BkonValue, stringTable: Map<string, number>) { value(
fastStringFormat: FastStringFormat,
object: BkonValue,
stringTable: Map<string, number>,
) {
if (object === null || object === undefined) { if (object === null || object === undefined) {
this.uint8(ValueType.Null); this.uint8(ValueType.Null);
} else if (typeof object === 'boolean') { } else if (typeof object === 'boolean') {
@@ -258,7 +266,19 @@ export class BkonWriteStream extends WriteStream {
} else if (typeof object === 'string') { } else if (typeof object === 'string') {
if (stringTable.has(object)) { if (stringTable.has(object)) {
this.uint8(ValueType.FastString); this.uint8(ValueType.FastString);
this.uint16(stringTable.get(object)!); const id = stringTable.get(object)!;
switch (fastStringFormat) {
case FastStringFormat.Format8:
this.uint8(id);
break;
case FastStringFormat.Format16:
this.uint16(id);
break;
case FastStringFormat.Format32:
this.uint32(id);
}
} else { } else {
this.uint8(ValueType.String); this.uint8(ValueType.String);
this.string(object); this.string(object);
@@ -266,14 +286,20 @@ export class BkonWriteStream extends WriteStream {
} else if (Array.isArray(object)) { } else if (Array.isArray(object)) {
this.uint8(ValueType.Array); this.uint8(ValueType.Array);
this.uint32(object.length); this.uint32(object.length);
object.forEach((value) => this.value(value, stringTable)); object.forEach((value) =>
this.value(fastStringFormat, value, stringTable),
);
} else { } else {
const entries = Object.entries(object); const entries = Object.entries(object);
this.uint8(ValueType.Object); this.uint8(ValueType.Object);
this.uint32(entries.length); this.uint32(entries.length);
entries.forEach(([key]) => this.value(key, stringTable)); entries.forEach(([key]) =>
entries.forEach(([, value]) => this.value(value, stringTable)); this.value(fastStringFormat, key, stringTable),
);
entries.forEach(([, value]) =>
this.value(fastStringFormat, value, stringTable),
);
} }
} }
@@ -286,21 +312,25 @@ export class BkonWriteStream extends WriteStream {
const stringTable = this.buildStringTable( const stringTable = this.buildStringTable(
this.collectStringCounts(object, new Map()), this.collectStringCounts(object, new Map()),
); );
let fastStringFormat: FastStringFormat;
if (stringTable.size <= 0xff) { if (stringTable.size <= 0xff) {
fastStringFormat = FastStringFormat.Format8;
this.uint8(FastStringFormat.Format8); this.uint8(FastStringFormat.Format8);
this.uint8(stringTable.size); this.uint8(stringTable.size);
} else if (stringTable.size <= 0xffff) { } else if (stringTable.size <= 0xffff) {
fastStringFormat = FastStringFormat.Format16;
this.uint8(FastStringFormat.Format16); this.uint8(FastStringFormat.Format16);
this.uint16(stringTable.size); this.uint16(stringTable.size);
} else { } else {
fastStringFormat = FastStringFormat.Format32;
this.uint8(FastStringFormat.Format32); this.uint8(FastStringFormat.Format32);
this.uint32(stringTable.size); this.uint32(stringTable.size);
} }
stringTable.forEach((_index, string) => this.string(string)); stringTable.forEach((_index, string) => this.string(string));
return stringTable; return { fastStringFormat, stringTable };
} }
buildStringTable(stringCounts: Map<string, number>) { buildStringTable(stringCounts: Map<string, number>) {