1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { Log } from '../../../utils/Log';
17import type { Releasable } from '../../common/Releasable';
18
19const TAG: string = 'common_FifoCache';
20
21export class FifoCache<T extends Releasable> {
22  map: Map<string, T> = new Map<string, T>();
23  pendingSet: Set<string> = new Set<string>();
24  limit: number;
25
26  constructor(limit: number) {
27    this.limit = limit || 5;
28  }
29
30  set(key: string, value: T) {
31    if (this.pendingSet.has(key)) {
32      this.pendingSet.delete(key);
33      Log.debug(TAG, `FifoCache add new pixmap: ${key} ${this.map.size}`);
34      if (this.map.has(key)) {
35        Log.debug(TAG, `FifoCache has same pixmap value: ${key} ${this.map.size}`);
36        value.release();
37        return;
38      }
39      this.map.set(key, value);
40    } else {
41      Log.error(TAG, `FifoCache add new pixmap failed because pending set don't have it: ${key}`);
42      value.release();
43    }
44  }
45
46  addPendingPixmap(key: string): boolean {
47    Log.debug(TAG, `FifoCache add pending pixmap: ${key} ${this.pendingSet.size}`);
48    if (!this.pendingSet.has(key)) {
49      this.pendingSet.add(key);
50      return true;
51    }
52    return false;
53  }
54
55  get(key: string): T {
56    Log.debug(TAG, `get: ${key}  map size: ${this.map.size}`);
57    if (this.map.has(key)) {
58      return this.map.get(key);
59    }
60    return undefined;
61  }
62
63  release(key: string): void {
64    Log.debug(TAG, `release: ${key}`);
65    if (this.pendingSet.has(key)) {
66      this.pendingSet.delete(key);
67    }
68    if (this.map.has(key)) {
69      let value = this.map.get(key);
70      value.release();
71      this.map.delete(key);
72    }
73  }
74
75  releaseAll(): void {
76    Log.debug(TAG, 'release all');
77    this.map.forEach((item) => {
78      item.release();
79    })
80    this.map.clear();
81    this.pendingSet.clear();
82  }
83}