diff --git a/js_api_module/buffer/js_buffer.cpp b/js_api_module/buffer/js_buffer.cpp index 800f17d3612ac47962c1ac8ec6635938064d499c..7e5513304de13b789373e54c1ebcccaaf05e3be4 100644 --- a/js_api_module/buffer/js_buffer.cpp +++ b/js_api_module/buffer/js_buffer.cpp @@ -27,6 +27,7 @@ void Buffer::Init(uint32_t size) HILOG_FATAL("Buffer:: constructor malloc failed"); length_ = 0; } + this->poolPtr_ = std::shared_ptr(raw_); } length_ = size; } @@ -38,6 +39,7 @@ void Buffer::Init(Buffer *buffer) if (raw_ == nullptr) { HILOG_FATAL("Buffer:: constructor malloc failed"); } else { + this->poolPtr_ = std::shared_ptr(this->raw_); this->length_ = buffer->length_; if (memcpy_s(raw_, length_, buffer->raw_ + buffer->byteOffset_, length_) != EOK) { HILOG_FATAL("Buffer:: constructor memcpy_s failed"); @@ -50,6 +52,9 @@ void Buffer::Init(Buffer *pool, unsigned int poolOffset, unsigned int length) { if (pool != nullptr) { this->raw_ = pool->GetRaw(); + if (this->raw_ != nullptr) { + this->poolPtr_ = std::shared_ptr(pool->poolPtr_); + } this->byteOffset_ = poolOffset; this->length_ = length; } @@ -66,13 +71,6 @@ void Buffer::Init(uint8_t *buffer, unsigned int byteOffset, unsigned int length) this->needRelease_ = false; } -Buffer::~Buffer() -{ - if (raw_ != nullptr && needRelease_) { - free(raw_); - raw_ = nullptr; - } -} EncodingType Buffer::GetEncodingType(std::string encode) { @@ -105,6 +103,11 @@ unsigned int Buffer::GetLength() return length_; } +unsigned int Buffer::GetSharedTimes() +{ + return poolPtr_.use_count(); +} + void Buffer::SetLength(unsigned int len) { length_ = len; diff --git a/js_api_module/buffer/js_buffer.h b/js_api_module/buffer/js_buffer.h index a43e0ee0f8e8535382ecc995dbf4a7fcad183f55..85644ecc8362ce96a194dbe4c8dc9a1360f3ffc2 100644 --- a/js_api_module/buffer/js_buffer.h +++ b/js_api_module/buffer/js_buffer.h @@ -16,6 +16,7 @@ #ifndef BUFFER_JS_BUFFER_H #define BUFFER_JS_BUFFER_H +#include #include #include #include @@ -29,13 +30,14 @@ namespace OHOS::buffer { class Buffer { public: Buffer() = default; - virtual ~Buffer(); + virtual ~Buffer() = default; void Init(uint32_t size); void Init(Buffer *buffer); void Init(Buffer *pool, unsigned int poolOffset, unsigned int length); void Init(uint8_t *buffer, unsigned int byteOffset, unsigned int length); unsigned int GetLength(); + unsigned int GetSharedTimes(); void SetLength(unsigned int len); unsigned int GetByteOffset(); int32_t Get(uint32_t index); @@ -93,6 +95,8 @@ private: unsigned int byteOffset_ {}; unsigned int length_ {}; bool needRelease_ {true}; + // delete data created by Buffer::Init automatically + std::shared_ptr poolPtr_; }; } // namespace OHOS::Buffer #endif // BUFFER_JS_BUFFER_H diff --git a/js_api_module/buffer/native_module_buffer.cpp b/js_api_module/buffer/native_module_buffer.cpp index 559f54856da48f05710fdf64fe4a82111aa60dab..eadf77fc9cfaf442a0e11345f72e2e44777762ff 100644 --- a/js_api_module/buffer/native_module_buffer.cpp +++ b/js_api_module/buffer/native_module_buffer.cpp @@ -517,6 +517,18 @@ static napi_value GetLength(napi_env env, napi_callback_info info) return result; } +static napi_value GetSharedTimes(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Buffer *buf = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast(&buf))); + uint32_t res = buf->GetSharedTimes(); + napi_value result = nullptr; + napi_create_uint32(env, res, &result); + return result; +} + static napi_value GetByteOffset(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; @@ -1158,6 +1170,7 @@ static napi_value BufferInit(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("readUInt32LE", ReadUInt32LE), DECLARE_NAPI_FUNCTION("setArray", SetArray), DECLARE_NAPI_FUNCTION("getLength", GetLength), + DECLARE_NAPI_FUNCTION("getSharedTimes", GetSharedTimes), DECLARE_NAPI_FUNCTION("getByteOffset", GetByteOffset), DECLARE_NAPI_FUNCTION("writeString", WriteString), DECLARE_NAPI_FUNCTION("fromString", FromString), diff --git a/js_api_module/buffer/src/js_buffer.ts b/js_api_module/buffer/src/js_buffer.ts index ff7eb84368e25e47330af6e77b64c28af4a90fbd..895816346a91f0575178aaa4957d161adc172ae8 100644 --- a/js_api_module/buffer/src/js_buffer.ts +++ b/js_api_module/buffer/src/js_buffer.ts @@ -286,10 +286,21 @@ const float64Array: Float64Array = new Float64Array(1); const uInt8Float64Array: Uint8Array = new Uint8Array(float64Array.buffer); const float32Array: Float32Array = new Float32Array(1); const uInt8Float32Array: Uint8Array = new Uint8Array(float32Array.buffer); +const maxPoolListSize = 128; + +interface ArkPrivate { + LinkedList: number; + Load(key: number): Object; +} +let arkPritvate: ArkPrivate = globalThis.ArkPrivate; +let LinkedList = undefined; +LinkedList = arkPritvate.Load(arkPritvate.LinkedList); +let poolList = new LinkedList(); function createPool(): void { poolSize = initialPoolSize; pool = new Buffer(poolSize); + poolList.add(pool); poolOffset = 0; } @@ -1963,7 +1974,7 @@ function concat(list: Buffer[] | Uint8Array[], totalLength?: number): Buffer { rangeErrorCheck(totalLength, 'totalLength', 0, UINT32MAX); - let buffer = alloc(totalLength); + let buffer = allocUninitializedFromPool(totalLength); let offset = 0; for (let i = 0, len = list.length; i < len; i++) { const buf = list[i]; @@ -1995,12 +2006,27 @@ function alloc(size: number, fill?: string | Buffer | number, encoding?: string) return buf; } +function UpdatePoolList() { + let length = poolList.length - 1; + for (let i = 0; i < length;) { + if (poolList.get(i)[bufferSymbol].getSharedTimes() != 1) { + i++; + continue; + } + poolList.removeByIndex(i); + length--; + } +} + function allocUninitializedFromPool(size: number): Buffer { sizeErrorCheck(size, 'size', ['number'], 0, MAX_LENGTH); if (!pool) { createPool(); } - if (size < (poolSize >>> 1)) { + if (poolList.length > maxPoolListSize) { + UpdatePoolList(); + } + if(poolList.length <= maxPoolListSize && size < (poolSize >>> 1)) { if (size > (poolSize - poolOffset)) { createPool(); } diff --git a/js_api_module/buffer/tsconfig.json b/js_api_module/buffer/tsconfig.json index 8dda14eceed2fb9c2dbe87f010147059e17da4d2..04c6658120629973741da9a7826a3c1959aea5a2 100644 --- a/js_api_module/buffer/tsconfig.json +++ b/js_api_module/buffer/tsconfig.json @@ -6,7 +6,6 @@ "outDir": "./out", /* Specify an output folder for all emitted files. */ "esModuleInterop": true, "forceConsistentCasingInFileNames": true, - "strict": true, "skipLibCheck": true, "noImplicitThis": false, "suppressImplicitAnyIndexErrors": true