/*
* Copyright (c) Huawei Device Co., Ltd. 2024-2025. All rights reserved.
* Licensed 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 { LogDomain, LogHelper } from '@ohos/basicutils';
const TAG = 'ObjectPool';
const log: LogHelper = LogHelper.getLogHelper(LogDomain.KG, TAG);
/**
* 可回收对象
*/
export interface Recyclable {
/**
* 回收方法
*/
recycle(): void;
}
/**
* 基础对象池实现
*/
export class ObjectPool<T extends Recyclable> {
/**
* 最大实例数
*/
private readonly _maxCount: number;
/**
* 全部实例
*/
private readonly _objs: Array<T>;
/**
* 空闲实例
*/
private readonly _idleObjs: Set<T> = new Set<T>();
/**
* 对象构造器
*/
private readonly _objectBuilder: () => T;
/**
* 真实大小
*/
private _realSize: number = 0;
/**
* 构造方法
*
* @param maxCount 最大实例数
*/
constructor(maxCount: number, objectBuilder: () => T) {
this._maxCount = maxCount;
this._objs = new Array<T>(maxCount);
this._objectBuilder = objectBuilder;
log.showDebug(`maxCount: ${maxCount}`);
}
/**
* 获取对象
*
* @returns 对象
*/
public acquire(): T | undefined {
if (this._idleObjs.size > 0) {
let idleObj: T = this._idleObjs.values().next().value;
this._idleObjs.delete(idleObj);
if (idleObj) {
log.showDebug(`idleObj: success.`);
return idleObj;
}
}
if (this._realSize < this._maxCount) {
let newObj = this._objectBuilder?.();
if (newObj) {
log.showDebug(`newObj: success.`);
this._objs.push(newObj);
this._realSize++;
return newObj;
}
}
log.showWarn(`acquire failed: <idle ${this._idleObjs.size}, current: ${this._realSize}, max: ${this._maxCount}>.`);
return undefined;
}
/**
* 归还对象
*
* @returns 对象
*/
public release(obj: T): void {
if (!obj || this.isReleased(obj)) {
return;
}
obj.recycle();
this._idleObjs.add(obj);
}
/**
* 判断对象是否空闲的
*
* @param obj 判断的对象
* @returns 是否空闲的
*/
public isReleased(obj: T): boolean {
return this._idleObjs.has(obj);
}
/**
* 销毁对象池
*/
public destroy(): void {
this._objs.forEach(obj => {
if (!this.isReleased(obj)) {
obj.recycle();
}
});
this._objs.length = 0;
this._idleObjs.clear();
}
}