From 20f1849353ace58804e7c09ef916d26c4b167dd9 Mon Sep 17 00:00:00 2001 From: weipeng Date: Tue, 2 Jan 2024 15:57:30 +0800 Subject: [PATCH] [JavaScript] Implement the standard protocol (#1286) 1. Make the tag string lazy to avoid creating strings. 2. Add the serializeVolatile API to take ownership of the bufferWriter and avoid buffer copying, which is 30% faster than the serialize operation. There is a usage limitation; the bufferWriter remains inaccessible until the dispose method from the result of serializeVolatile has been called. 4. Remove the useLatin1 configuration, which is a standard in the Fury protocol. Before: ![image](https://github.com/apache/incubator-fury/assets/16490211/aa8cba42-aafd-4f5b-ab73-2ac698dc8726) After: ![image](https://github.com/apache/incubator-fury/assets/16490211/106ea85c-be7d-4bfe-98b1-05d766b43035) --- javascript/benchmark/index.js | 2 +- javascript/benchmark/sample.jpg | Bin 0 -> 27259 bytes javascript/packages/fury/index.ts | 7 ++ javascript/packages/fury/lib/classResolver.ts | 50 ++++++++++--- javascript/packages/fury/lib/error.ts | 28 ++++++++ javascript/packages/fury/lib/fury.ts | 24 ++++++- .../fury/lib/internalSerializer/number.ts | 8 +-- javascript/packages/fury/lib/reader.ts | 9 ++- javascript/packages/fury/lib/type.ts | 1 - javascript/packages/fury/lib/writer.ts | 26 +++++-- javascript/test/array.test.ts | 2 +- javascript/test/io.test.ts | 20 ++---- javascript/test/protocol/struct.test.ts | 52 -------------- javascript/test/reader.test.ts | 5 -- javascript/test/string.test.ts | 2 - javascript/test/writer.test.ts | 66 ++++++++++++++++++ 16 files changed, 201 insertions(+), 101 deletions(-) create mode 100644 javascript/benchmark/sample.jpg create mode 100644 javascript/packages/fury/lib/error.ts create mode 100644 javascript/test/writer.test.ts diff --git a/javascript/benchmark/index.js b/javascript/benchmark/index.js index eb74e30536..5dd96f0fb1 100644 --- a/javascript/benchmark/index.js +++ b/javascript/benchmark/index.js @@ -20,7 +20,7 @@ const Fury = require("@furyjs/fury"); const utils = require("../test/util"); const hps = require('@furyjs/hps'); -const fury = new Fury.default({ hps, refTracking: false, useLatin1: true, useSliceString: true }); +const fury = new Fury.default({ hps, refTracking: false, useSliceString: true }); const Benchmark = require("benchmark"); const protobuf = require("protobufjs"); const path = require('path'); diff --git a/javascript/benchmark/sample.jpg b/javascript/benchmark/sample.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5c98c2d23edf0a529fe9686434c344fe6fbae9dd GIT binary patch literal 27259 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 => { return this.fury.serialize(data, serializer); }, + serializeVolatile: (data: ToRecordType) => { + return this.fury.serializeVolatile(data, serializer); + }, deserialize: (bytes: Uint8Array) => { return this.fury.deserialize(bytes, serializer) as ToRecordType; }, }; } + serializeVolatile(v: any, serialize?: Serializer) { + return this.fury.serializeVolatile(v, serialize); + } + serialize(v: any, serialize?: Serializer) { return this.fury.serialize(v, serialize); } diff --git a/javascript/packages/fury/lib/classResolver.ts b/javascript/packages/fury/lib/classResolver.ts index e2553ad81c..d344e511b4 100644 --- a/javascript/packages/fury/lib/classResolver.ts +++ b/javascript/packages/fury/lib/classResolver.ts @@ -34,12 +34,39 @@ import { BinaryWriter } from "./writer"; const USESTRINGVALUE = 0; const USESTRINGID = 1; +class Lazystring { + private string: string | null = null; + private start: number | null = null; + private len: number | null = null; + + static fromPair(start: number, len: number) { + const result = new Lazystring(); + result.start = start; + result.len = len; + return result; + } + + static fromString(str: string) { + const result = new Lazystring(); + result.string = str; + return result; + } + + toString(binaryReader: BinaryReader) { + if (this.string == null) { + const str = binaryReader.stringUtf8At(this.start!, this.len!); + return str; + } + return this.string; + } +} + export default class SerializerResolver { private internalSerializer: Serializer[] = new Array(300); private customSerializer: { [key: string]: Serializer } = { }; - private readStringPool: string[] = []; + private readStringPool: Lazystring[] = []; private writeStringCount = 0; private writeStringIndex: number[] = []; @@ -139,10 +166,9 @@ export default class SerializerResolver { const flag = binaryReader.uint8(); if (flag === USESTRINGVALUE) { binaryReader.skip(8); // The tag hash is not needed at the moment. - const str = binaryReader.stringUtf8(binaryReader.int16()); - return str; + return binaryReader.stringUtf8(binaryReader.int16()); } else { - return this.readStringPool[binaryReader.int16()]; + return this.readStringPool[binaryReader.int16()].toString(binaryReader); } } @@ -150,11 +176,19 @@ export default class SerializerResolver { const flag = binaryReader.uint8(); if (flag === USESTRINGVALUE) { binaryReader.skip(8); // The tag hash is not needed at the moment. - const str = binaryReader.stringUtf8(binaryReader.int16()); - this.readStringPool.push(str); - return str; + const start = binaryReader.getCursor(); + const len = binaryReader.int16(); + binaryReader.skip(len); + this.readStringPool.push(Lazystring.fromPair(start, len)); + const idx = this.readStringPool.length; + return () => { + return this.readStringPool[idx - 1].toString(binaryReader); + }; } else { - return this.readStringPool[binaryReader.int16()]; + const idx = binaryReader.int16(); + return () => { + return this.readStringPool[idx].toString(binaryReader); + }; } } } diff --git a/javascript/packages/fury/lib/error.ts b/javascript/packages/fury/lib/error.ts new file mode 100644 index 0000000000..2c8d3ed914 --- /dev/null +++ b/javascript/packages/fury/lib/error.ts @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export class OwnershipError extends Error { + constructor(message: string) { + super(message); + this.name = this.constructor.name; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + } +} diff --git a/javascript/packages/fury/lib/fury.ts b/javascript/packages/fury/lib/fury.ts index fc77993944..5c4c3cef4b 100644 --- a/javascript/packages/fury/lib/fury.ts +++ b/javascript/packages/fury/lib/fury.ts @@ -22,6 +22,7 @@ import { BinaryWriter } from "./writer"; import { BinaryReader } from "./reader"; import { ReferenceResolver } from "./referenceResolver"; import { ConfigFlags, Serializer, Config, InternalSerializerType, Language } from "./type"; +import { OwnershipError } from "./error"; export default (config: Config) => { const binaryReader = BinaryReader(config); @@ -38,6 +39,7 @@ export default (config: Config) => { classResolver, binaryReader, binaryWriter, + serializeVolatile, }; classResolver.init(fury); @@ -71,10 +73,17 @@ export default (config: Config) => { } } - function serialize(data: T, serializer?: Serializer) { + function serializeInternal(data: T, serializer?: Serializer) { + try { + binaryWriter.reset(); + } catch (e) { + if (e instanceof OwnershipError) { + throw new Error("Permission denied. To release the serialization ownership, you must call the dispose function returned by serializeVolatile."); + } + throw e; + } referenceResolver.reset(); classResolver.reset(); - binaryWriter.reset(); let bitmap = 0; if (data === null) { bitmap |= ConfigFlags.isNullFlag; @@ -92,7 +101,16 @@ export default (config: Config) => { classResolver.getSerializerById(InternalSerializerType.ANY).write(data); } binaryWriter.setUint32Position(cursor, binaryWriter.getCursor()); // nativeObjects start offsets; - return binaryWriter.dump(); + return binaryWriter; + } + + function serialize(data: T, serializer?: Serializer) { + return serializeInternal(data, serializer).dump(); + } + + function serializeVolatile(data: T, serializer?: Serializer) { + return serializeInternal(data, serializer).dumpAndOwn(); } + return fury; }; diff --git a/javascript/packages/fury/lib/internalSerializer/number.ts b/javascript/packages/fury/lib/internalSerializer/number.ts index 7d0789fd09..87cd6b148e 100644 --- a/javascript/packages/fury/lib/internalSerializer/number.ts +++ b/javascript/packages/fury/lib/internalSerializer/number.ts @@ -21,7 +21,7 @@ import { InternalSerializerType, RefFlags, Fury } from "../type"; export const uInt8Serializer = (fury: Fury) => { const { binaryWriter, binaryReader, referenceResolver } = fury; - const { int8: writeInt8, uint8: writeUInt8 } = binaryWriter; + const { uint8: writeUInt8 } = binaryWriter; const { uint8: readUInt8 } = binaryReader; return { ...referenceResolver.deref(() => { @@ -107,7 +107,7 @@ export const int8Serializer = (fury: Fury) => { export const uInt16Serializer = (fury: Fury) => { const { binaryWriter, binaryReader, referenceResolver } = fury; - const { int8: writeInt8, uint16: writeUInt16 } = binaryWriter; + const { uint16: writeUInt16 } = binaryWriter; const { uint16: readUInt16 } = binaryReader; return { @@ -151,7 +151,7 @@ export const int16Serializer = (fury: Fury) => { export const uInt32Serializer = (fury: Fury) => { const { binaryWriter, binaryReader, referenceResolver } = fury; - const { int8: writeInt8, uint32: writeUInt32 } = binaryWriter; + const { uint32: writeUInt32 } = binaryWriter; const { uint32: readUInt32 } = binaryReader; return { @@ -195,7 +195,7 @@ export const int32Serializer = (fury: Fury) => { export const uInt64Serializer = (fury: Fury) => { const { binaryWriter, binaryReader, referenceResolver } = fury; - const { int8: writeInt8, uint64: writeUInt64 } = binaryWriter; + const { uint64: writeUInt64 } = binaryWriter; const { uint64: readUInt64 } = binaryReader; return { diff --git a/javascript/packages/fury/lib/reader.ts b/javascript/packages/fury/lib/reader.ts index 80e479d909..6b275f1d32 100644 --- a/javascript/packages/fury/lib/reader.ts +++ b/javascript/packages/fury/lib/reader.ts @@ -99,6 +99,10 @@ export const BinaryReader = (config: Config) => { return result; } + function stringUtf8At(start: number, len: number) { + return buffer.utf8Slice(start, start + len); + } + function stringUtf8(len: number) { const result = buffer.utf8Slice(cursor, cursor + len); cursor += len; @@ -106,9 +110,9 @@ export const BinaryReader = (config: Config) => { } function stringOfVarInt32() { - const useLatin1 = config.useLatin1 ? uint8() === LATIN1 : false; + const isLatin1 = uint8() === LATIN1; const len = varInt32(); - return useLatin1 ? stringLatin1(len) : stringUtf8(len); + return isLatin1 ? stringLatin1(len) : stringUtf8(len); } function stringLatin1Fast(len: number) { @@ -167,6 +171,7 @@ export const BinaryReader = (config: Config) => { bufferRef, uint8, reset, + stringUtf8At, stringUtf8, stringLatin1, stringOfVarInt32, diff --git a/javascript/packages/fury/lib/type.ts b/javascript/packages/fury/lib/type.ts index 2d6606b297..39cd50669f 100644 --- a/javascript/packages/fury/lib/type.ts +++ b/javascript/packages/fury/lib/type.ts @@ -109,7 +109,6 @@ export interface Hps { export interface Config { hps?: Hps refTracking?: boolean - useLatin1?: boolean useSliceString?: boolean } diff --git a/javascript/packages/fury/lib/writer.ts b/javascript/packages/fury/lib/writer.ts index 01f11f644b..57ea680f86 100644 --- a/javascript/packages/fury/lib/writer.ts +++ b/javascript/packages/fury/lib/writer.ts @@ -19,6 +19,7 @@ import { Config, LATIN1, UTF8 } from "./type"; import { PlatformBuffer, alloc, strByteLength } from "./platformBuffer"; +import { OwnershipError } from "./error"; const MAX_POOL_SIZE = 1024 * 1024 * 3; // 3MB @@ -28,6 +29,7 @@ export const BinaryWriter = (config: Config) => { let arrayBuffer: PlatformBuffer; let dataView: DataView; let reserved = 0; + let locked = false; function initPoll() { byteLength = 1024 * 100; @@ -49,6 +51,9 @@ export const BinaryWriter = (config: Config) => { } function reset() { + if (locked) { + throw new OwnershipError("Ownership of writer was held by dumpAndOwn, but not released"); + } cursor = 0; reserved = 0; } @@ -170,9 +175,7 @@ export const BinaryWriter = (config: Config) => { return function (v: string) { const isLatin1 = detectIsLatin1(v); const len = isLatin1 ? v.length : strByteLength(v); - if (config.useLatin1) { - dataView.setUint8(cursor++, isLatin1 ? LATIN1 : UTF8); - } + dataView.setUint8(cursor++, isLatin1 ? LATIN1 : UTF8); varInt32(len); reserve(len); if (isLatin1) { @@ -191,9 +194,7 @@ export const BinaryWriter = (config: Config) => { function stringOfVarInt32Slow(v: string) { const len = strByteLength(v); const isLatin1 = len === v.length; - if (config.useLatin1) { - dataView.setUint8(cursor++, isLatin1 ? LATIN1 : UTF8); - } + dataView.setUint8(cursor++, isLatin1 ? LATIN1 : UTF8); varInt32(len); reserve(len); if (isLatin1) { @@ -236,6 +237,18 @@ export const BinaryWriter = (config: Config) => { return result; } + function dumpAndOwn() { + locked = true; + return { + get() { + return arrayBuffer.subarray(0, cursor); + }, + dispose() { + locked = false; + }, + }; + } + function getCursor() { return cursor; } @@ -278,5 +291,6 @@ export const BinaryWriter = (config: Config) => { int32, getCursor, setUint32Position, + dumpAndOwn, }; }; diff --git a/javascript/test/array.test.ts b/javascript/test/array.test.ts index 98c36af159..ea9c7d2217 100644 --- a/javascript/test/array.test.ts +++ b/javascript/test/array.test.ts @@ -122,7 +122,7 @@ describe('array', () => { } }; - const fury = new Fury({ refTracking: true, useLatin1: true }); + const fury = new Fury({ refTracking: true }); const serializer = fury.registerSerializer(description).serializer; const input = fury.serialize({ a7: ["hello", "world", null] diff --git a/javascript/test/io.test.ts b/javascript/test/io.test.ts index 03487315f2..040c9c7e2c 100644 --- a/javascript/test/io.test.ts +++ b/javascript/test/io.test.ts @@ -30,11 +30,7 @@ function num2Bin(num: number) { [ { - useLatin1: true, useSliceString: true, - }, - { - useLatin1: false, } ].forEach((config: Config) => { describe('writer', () => { @@ -186,9 +182,7 @@ function num2Bin(num: number) { const ab = writer.dump(); const reader = BinaryReader(config); reader.reset(ab); - if (config.useLatin1) { - expect(reader.uint8()).toBe(0); - } + expect(reader.uint8()).toBe(0); const len = reader.varInt32(); expect(len).toBe(11); const str = reader.stringLatin1(11); @@ -202,9 +196,7 @@ function num2Bin(num: number) { const ab = writer.dump(); const reader = BinaryReader(config); reader.reset(ab); - if (config.useLatin1) { - expect(reader.uint8()).toBe(0); - } + expect(reader.uint8()).toBe(0); const len = reader.varInt32(); expect(len).toBe(110); expect(reader.stringLatin1(len)).toBe(str); @@ -219,9 +211,7 @@ function num2Bin(num: number) { { reader.reset(ab); - if (config.useLatin1) { - expect(reader.uint8()).toBe(1); - } + expect(reader.uint8()).toBe(1); const len = reader.varInt32(); expect(len).toBe(17); expect(reader.stringUtf8(len)).toBe(str); @@ -240,9 +230,7 @@ function num2Bin(num: number) { const reader = BinaryReader(config); { reader.reset(ab); - if (config.useLatin1) { - expect(reader.uint8()).toBe(1); - } + expect(reader.uint8()).toBe(1); const len = reader.varInt32(); expect(len).toBe(170); expect(reader.stringUtf8(len)).toBe(str); diff --git a/javascript/test/protocol/struct.test.ts b/javascript/test/protocol/struct.test.ts index 4e5416330b..0dd3141919 100644 --- a/javascript/test/protocol/struct.test.ts +++ b/javascript/test/protocol/struct.test.ts @@ -43,58 +43,6 @@ describe('protocol', () => { const result = deserialize(bf); expect(result).toEqual(obj); }); - test('should py bin work', () => { - - const fury = new Fury({ refTracking: true }); - const { deserialize } = fury.registerSerializer({ - type: InternalSerializerType.FURY_TYPE_TAG, - options: { - tag: "example.ComplexObject", - props: { - f1: Type.string(), - f2: Type.map(Type.string(), Type.any()), - f3: Type.int8(), - f4: Type.int16(), - f5: Type.int32(), - f6: Type.int64(), - f7: Type.float(), - f8: Type.double(), - f9: Type.array(Type.int16()), - f10: Type.map(Type.int32(), Type.double()), - } - } - }); - - const obj = deserialize(new Uint8Array([ - 134, 2, 179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 81, 159, 160, 124, 69, 240, 2, 120, 21, 0, - 101, 120, 97, 109, 112, 108, 101, 46, 67, 111, 109, 112, 108, 101, 120, 79, 98, 106, 101, - 99, 116, 71, 168, 32, 21, 0, 13, 0, 3, 115, 116, 114, 0, 30, 0, 2, 255, 7, 0, 1, 0, 0, 0, - 255, 12, 0, 85, 85, 85, 85, 85, 85, 213, 63, 255, 7, 0, 100, 0, 0, 0, 255, 12, 0, 146, 36, - 73, 146, 36, 73, 210, 63, 0, 30, 0, 2, 0, 13, 0, 2, 107, 49, 255, 3, 0, 255, 0, 13, 0, 2, - 107, 50, 255, 3, 0, 2, 255, 3, 0, 127, 255, 5, 0, 255, 127, 255, 7, 0, 255, 255, 255, 127, - 255, 9, 0, 255, 255, 255, 255, 255, 255, 255, 127, 255, 11, 0, 0, 0, 0, 63, 255, 12, 0, 85, - 85, 85, 85, 85, 85, 229, 63, 0, 25, 0, 2, 255, 5, 0, 1, 0, 255, 5, 0, 2, 0, 134, 2, 98, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 81, 159, 160, 124, 69, 240, 2, 120, 21, 0, 101, 120, 97, 109, - 112, 108, 101, 46, 67, 111, 109, 112, 108, 101, 120, 79, 98, 106, 101, 99, 116, 71, 168, - 32, 21, 253, 253, 253, 255, 3, 0, 0, 255, 5, 0, 0, 0, 255, 7, 0, 0, 0, 0, 0, 255, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 11, 0, 171, 170, 170, 62, 255, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 253, - ])); - obj.f6 = Number(obj.f6) - - expect(obj).toEqual({ - f1: "str", - f10: new Map([[1, 1 / 3], [100, 2 / 7]]), - f2: new Map([['k1', -1], ['k2', 2]]), - f3: 2**7 - 1, - f4: 2**15 - 1, - f5: 2**31 - 1, - f6: 2**63 - 1, - f7: 1 / 2, - f8: 2 / 3, - f9: [1, 2] - }) - }); }); diff --git a/javascript/test/reader.test.ts b/javascript/test/reader.test.ts index c627d04529..0e0e6dc699 100644 --- a/javascript/test/reader.test.ts +++ b/javascript/test/reader.test.ts @@ -28,11 +28,6 @@ const hps = process.env.enableHps ? require('@furyjs/hps') : null; [ { - useLatin1: true, - hps, - }, - { - useLatin1: false, hps, } ].forEach((config: Config) => { diff --git a/javascript/test/string.test.ts b/javascript/test/string.test.ts index 4aefb8f8bc..a736f7925c 100644 --- a/javascript/test/string.test.ts +++ b/javascript/test/string.test.ts @@ -23,11 +23,9 @@ const hps = require('@furyjs/hps'); [ { hps, - useLatin1: true }, { hps: null, - useLatin1: false } ].forEach(config => { describe('string', () => { diff --git a/javascript/test/writer.test.ts b/javascript/test/writer.test.ts new file mode 100644 index 0000000000..caf9e599ff --- /dev/null +++ b/javascript/test/writer.test.ts @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { OwnershipError } from '@furyjs/fury/lib/error'; +import { BinaryWriter } from '@furyjs/fury/lib/writer'; +import { describe, expect, test } from '@jest/globals'; + +describe('writer', () => { + test('should dumpOwn dispose work', () => { + const writer = BinaryWriter({}); + { + writer.uint8(256); + const { get, dispose } = writer.dumpAndOwn(); + const ab = get(); + expect(ab.byteLength).toBe(1); + expect(ab[0]).toBe(0); + expect(writer.getCursor()).toBe(1); + dispose(); + } + writer.reset(); + { + writer.uint8(256); + const { get, dispose } = writer.dumpAndOwn(); + const ab = get(); + expect(ab.byteLength).toBe(1); + expect(ab[0]).toBe(0); + expect(writer.getCursor()).toBe(1); + dispose(); + } + }); + + test('should dumpOwn work', () => { + const writer = BinaryWriter({}); + { + writer.uint8(256); + const { get } = writer.dumpAndOwn(); + const ab = get(); + expect(ab.byteLength).toBe(1); + expect(ab[0]).toBe(0); + expect(writer.getCursor()).toBe(1); + } + try { + writer.reset(); + } catch (error) { + expect(error instanceof OwnershipError).toBe(true); + return; + } + throw new Error("unreachable code") + }); +}); \ No newline at end of file