@ckb-ccc/core 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @ckb-ccc/core
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#116](https://github.com/ckb-devrel/ccc/pull/116) [`128e87b`](https://github.com/ckb-devrel/ccc/commit/128e87b5ca3e97bfe7842e76f786aa6aec010797) Thanks [@Hanssen0](https://github.com/Hanssen0)! - feat: Client LRU cache
8
+
3
9
  ## 1.1.1
4
10
 
5
11
  ### Patch Changes
@@ -1,10 +1,22 @@
1
- import { CellLike, ScriptLike } from "../../ckb/index.js";
1
+ import { Cell, CellLike, ScriptLike } from "../../ckb/index.js";
2
2
  import { HexLike } from "../../hex/index.js";
3
3
  import { NumLike } from "../../num/index.js";
4
4
  import { ClientCollectableSearchKeyLike } from "../clientTypes.advanced.js";
5
+ export type CellRecord = [
6
+ false,
7
+ Pick<Cell, "outPoint"> & Partial<Pick<Cell, "cellOutput" | "outputData">>
8
+ ] | [true, Cell] | [undefined, Cell];
5
9
  export declare function filterData(dataLike: HexLike, filterLike: HexLike | undefined, filterMode: "exact" | "prefix" | "partial"): boolean;
6
10
  export declare function filterScript(valueLike: ScriptLike | undefined, filterLike: ScriptLike | undefined, filterMode: "prefix" | "exact" | "partial"): boolean;
7
11
  export declare function filterNumByRange(lengthLike: NumLike, range: [NumLike, NumLike] | undefined): boolean;
8
12
  export declare function filterScriptByLenRange(valueLike?: ScriptLike, scriptLenRange?: [NumLike, NumLike]): boolean;
9
13
  export declare function filterCell(searchKeyLike: ClientCollectableSearchKeyLike, cellLike: CellLike): boolean;
14
+ export declare class MapLru<K, V> extends Map<K, V> {
15
+ private readonly capacity;
16
+ private readonly lru;
17
+ constructor(capacity: number);
18
+ access(key: K): void;
19
+ get(key: K): V | undefined;
20
+ set(key: K, value: V): this;
21
+ }
10
22
  //# sourceMappingURL=memory.advanced.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory.advanced.d.ts","sourceRoot":"","sources":["../../../src/client/cache/memory.advanced.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,QAAQ,EAAU,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAW,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAW,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,8BAA8B,EAE/B,MAAM,4BAA4B,CAAC;AAGpC,wBAAgB,UAAU,CACxB,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,OAAO,GAAG,SAAS,EAC/B,UAAU,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GACzC,OAAO,CAgBT;AAED,wBAAgB,YAAY,CAC1B,SAAS,EAAE,UAAU,GAAG,SAAS,EACjC,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,UAAU,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GACzC,OAAO,CAkBT;AAED,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,SAAS,GACpC,OAAO,CAQT;AAED,wBAAgB,sBAAsB,CACpC,SAAS,CAAC,EAAE,UAAU,EACtB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,GAClC,OAAO,CAYT;AAED,wBAAgB,UAAU,CACxB,aAAa,EAAE,8BAA8B,EAC7C,QAAQ,EAAE,QAAQ,GACjB,OAAO,CA4CT"}
1
+ {"version":3,"file":"memory.advanced.d.ts","sourceRoot":"","sources":["../../../src/client/cache/memory.advanced.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAU,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAW,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAW,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,8BAA8B,EAE/B,MAAM,4BAA4B,CAAC;AAIpC,MAAM,MAAM,UAAU,GAClB;IACE,KAAK;IACL,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY,CAAC,CAAC;CAC1E,GACD,CAAC,IAAI,EAAE,IAAI,CAAC,GACZ,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAEtB,wBAAgB,UAAU,CACxB,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,OAAO,GAAG,SAAS,EAC/B,UAAU,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GACzC,OAAO,CAgBT;AAED,wBAAgB,YAAY,CAC1B,SAAS,EAAE,UAAU,GAAG,SAAS,EACjC,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,UAAU,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GACzC,OAAO,CAkBT;AAED,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,SAAS,GACpC,OAAO,CAQT;AAED,wBAAgB,sBAAsB,CACpC,SAAS,CAAC,EAAE,UAAU,EACtB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,GAClC,OAAO,CAYT;AAED,wBAAgB,UAAU,CACxB,aAAa,EAAE,8BAA8B,EAC7C,QAAQ,EAAE,QAAQ,GACjB,OAAO,CA4CT;AAED,qBAAa,MAAM,CAAC,CAAC,EAAE,CAAC,CAAE,SAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IAG7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAFrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAW;gBAEF,QAAQ,EAAE,MAAM;IAI7C,MAAM,CAAC,GAAG,EAAE,CAAC;IAYb,GAAG,CAAC,GAAG,EAAE,CAAC;IAKV,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;CAIrB"}
@@ -78,3 +78,29 @@ export function filterCell(searchKeyLike, cellLike) {
78
78
  }
79
79
  return true;
80
80
  }
81
+ export class MapLru extends Map {
82
+ constructor(capacity) {
83
+ super();
84
+ this.capacity = capacity;
85
+ this.lru = [];
86
+ }
87
+ access(key) {
88
+ const index = this.lru.indexOf(key);
89
+ if (index !== -1) {
90
+ this.lru.splice(index, 1);
91
+ }
92
+ this.lru.push(key);
93
+ if (this.lru.length > this.capacity) {
94
+ this.delete(this.lru[0]);
95
+ this.lru.shift();
96
+ }
97
+ }
98
+ get(key) {
99
+ this.access(key);
100
+ return super.get(key);
101
+ }
102
+ set(key, value) {
103
+ this.access(key);
104
+ return super.set(key, value);
105
+ }
106
+ }
@@ -3,6 +3,8 @@ import { HexLike } from "../../hex/index.js";
3
3
  import { ClientCollectableSearchKeyLike } from "../clientTypes.advanced.js";
4
4
  import { ClientCache } from "./cache.js";
5
5
  export declare class ClientCacheMemory extends ClientCache {
6
+ private readonly maxCells;
7
+ private readonly maxTxs;
6
8
  /**
7
9
  * OutPoint => [isLive, Cell | OutPoint]
8
10
  */
@@ -11,6 +13,7 @@ export declare class ClientCacheMemory extends ClientCache {
11
13
  * TX Hash => Transaction
12
14
  */
13
15
  private readonly knownTransactions;
16
+ constructor(maxCells?: number, maxTxs?: number);
14
17
  markUsable(...cellLikes: (CellLike | CellLike[])[]): Promise<void>;
15
18
  markUnusable(...outPointLikes: (OutPointLike | OutPointLike[])[]): Promise<void>;
16
19
  clear(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/client/cache/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,QAAQ,EAER,YAAY,EACZ,WAAW,EACX,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAW,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,8BAA8B,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC,qBAAa,iBAAkB,SAAQ,WAAW;IAChD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CASR;IAEd;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAuC;IAEnE,UAAU,CAAC,GAAG,SAAS,EAAE,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IASlE,YAAY,CAChB,GAAG,aAAa,EAAE,CAAC,YAAY,GAAG,YAAY,EAAE,CAAC,EAAE,GAClD,OAAO,CAAC,IAAI,CAAC;IAcV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB,SAAS,CACd,OAAO,EAAE,8BAA8B,GACtC,cAAc,CAAC,IAAI,CAAC;IAYjB,OAAO,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAS9D,UAAU,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAMxD,kBAAkB,CACtB,GAAG,YAAY,EAAE,CAAC,eAAe,GAAG,eAAe,EAAE,CAAC,EAAE,GACvD,OAAO,CAAC,IAAI,CAAC;IAMV,cAAc,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAKrE,WAAW,CAAC,GAAG,KAAK,EAAE,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAWtE"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/client/cache/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,QAAQ,EAER,YAAY,EACZ,WAAW,EACX,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAW,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,8BAA8B,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC,qBAAa,iBAAkB,SAAQ,WAAW;IAY9C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAZzB;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IAEnD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA8B;gBAG7C,QAAQ,SAAM,EACd,MAAM,SAAM;IAQzB,UAAU,CAAC,GAAG,SAAS,EAAE,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IASlE,YAAY,CAChB,GAAG,aAAa,EAAE,CAAC,YAAY,GAAG,YAAY,EAAE,CAAC,EAAE,GAClD,OAAO,CAAC,IAAI,CAAC;IAcV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKrB,SAAS,CACd,OAAO,EAAE,8BAA8B,GACtC,cAAc,CAAC,IAAI,CAAC;IAajB,OAAO,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAS9D,UAAU,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAMxD,kBAAkB,CACtB,GAAG,YAAY,EAAE,CAAC,eAAe,GAAG,eAAe,EAAE,CAAC,EAAE,GACvD,OAAO,CAAC,IAAI,CAAC;IAMV,cAAc,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAKrE,WAAW,CAAC,GAAG,KAAK,EAAE,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAWtE"}
@@ -1,18 +1,14 @@
1
1
  import { Cell, OutPoint, Transaction, } from "../../ckb/index.js";
2
2
  import { hexFrom } from "../../hex/index.js";
3
3
  import { ClientCache } from "./cache.js";
4
- import { filterCell } from "./memory.advanced.js";
4
+ import { filterCell, MapLru } from "./memory.advanced.js";
5
5
  export class ClientCacheMemory extends ClientCache {
6
- constructor() {
7
- super(...arguments);
8
- /**
9
- * OutPoint => [isLive, Cell | OutPoint]
10
- */
11
- this.cells = new Map();
12
- /**
13
- * TX Hash => Transaction
14
- */
15
- this.knownTransactions = new Map();
6
+ constructor(maxCells = 512, maxTxs = 256) {
7
+ super();
8
+ this.maxCells = maxCells;
9
+ this.maxTxs = maxTxs;
10
+ this.cells = new MapLru(this.maxCells);
11
+ this.knownTransactions = new MapLru(this.maxTxs);
16
12
  }
17
13
  async markUsable(...cellLikes) {
18
14
  cellLikes.flat().forEach((cellLike) => {
@@ -34,18 +30,18 @@ export class ClientCacheMemory extends ClientCache {
34
30
  });
35
31
  }
36
32
  async clear() {
37
- for (const val of this.cells.values()) {
38
- val[0] = undefined;
39
- }
33
+ this.cells.clear();
34
+ this.knownTransactions.clear();
40
35
  }
41
36
  async *findCells(keyLike) {
42
- for (const [isLive, cell] of this.cells.values()) {
37
+ for (const [key, [isLive, cell]] of this.cells.entries()) {
43
38
  if (!isLive) {
44
39
  continue;
45
40
  }
46
41
  if (!filterCell(keyLike, cell)) {
47
42
  continue;
48
43
  }
44
+ this.cells.access(key);
49
45
  yield cell.clone();
50
46
  }
51
47
  }
@@ -1,10 +1,22 @@
1
- import { CellLike, ScriptLike } from "../../ckb/index.js";
1
+ import { Cell, CellLike, ScriptLike } from "../../ckb/index.js";
2
2
  import { HexLike } from "../../hex/index.js";
3
3
  import { NumLike } from "../../num/index.js";
4
4
  import { ClientCollectableSearchKeyLike } from "../clientTypes.advanced.js";
5
+ export type CellRecord = [
6
+ false,
7
+ Pick<Cell, "outPoint"> & Partial<Pick<Cell, "cellOutput" | "outputData">>
8
+ ] | [true, Cell] | [undefined, Cell];
5
9
  export declare function filterData(dataLike: HexLike, filterLike: HexLike | undefined, filterMode: "exact" | "prefix" | "partial"): boolean;
6
10
  export declare function filterScript(valueLike: ScriptLike | undefined, filterLike: ScriptLike | undefined, filterMode: "prefix" | "exact" | "partial"): boolean;
7
11
  export declare function filterNumByRange(lengthLike: NumLike, range: [NumLike, NumLike] | undefined): boolean;
8
12
  export declare function filterScriptByLenRange(valueLike?: ScriptLike, scriptLenRange?: [NumLike, NumLike]): boolean;
9
13
  export declare function filterCell(searchKeyLike: ClientCollectableSearchKeyLike, cellLike: CellLike): boolean;
14
+ export declare class MapLru<K, V> extends Map<K, V> {
15
+ private readonly capacity;
16
+ private readonly lru;
17
+ constructor(capacity: number);
18
+ access(key: K): void;
19
+ get(key: K): V | undefined;
20
+ set(key: K, value: V): this;
21
+ }
10
22
  //# sourceMappingURL=memory.advanced.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory.advanced.d.ts","sourceRoot":"","sources":["../../../src/client/cache/memory.advanced.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,QAAQ,EAAU,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAW,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAW,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,8BAA8B,EAE/B,MAAM,4BAA4B,CAAC;AAGpC,wBAAgB,UAAU,CACxB,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,OAAO,GAAG,SAAS,EAC/B,UAAU,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GACzC,OAAO,CAgBT;AAED,wBAAgB,YAAY,CAC1B,SAAS,EAAE,UAAU,GAAG,SAAS,EACjC,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,UAAU,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GACzC,OAAO,CAkBT;AAED,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,SAAS,GACpC,OAAO,CAQT;AAED,wBAAgB,sBAAsB,CACpC,SAAS,CAAC,EAAE,UAAU,EACtB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,GAClC,OAAO,CAYT;AAED,wBAAgB,UAAU,CACxB,aAAa,EAAE,8BAA8B,EAC7C,QAAQ,EAAE,QAAQ,GACjB,OAAO,CA4CT"}
1
+ {"version":3,"file":"memory.advanced.d.ts","sourceRoot":"","sources":["../../../src/client/cache/memory.advanced.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAU,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAW,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAW,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,8BAA8B,EAE/B,MAAM,4BAA4B,CAAC;AAIpC,MAAM,MAAM,UAAU,GAClB;IACE,KAAK;IACL,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY,CAAC,CAAC;CAC1E,GACD,CAAC,IAAI,EAAE,IAAI,CAAC,GACZ,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAEtB,wBAAgB,UAAU,CACxB,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,OAAO,GAAG,SAAS,EAC/B,UAAU,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GACzC,OAAO,CAgBT;AAED,wBAAgB,YAAY,CAC1B,SAAS,EAAE,UAAU,GAAG,SAAS,EACjC,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,UAAU,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GACzC,OAAO,CAkBT;AAED,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,SAAS,GACpC,OAAO,CAQT;AAED,wBAAgB,sBAAsB,CACpC,SAAS,CAAC,EAAE,UAAU,EACtB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,GAClC,OAAO,CAYT;AAED,wBAAgB,UAAU,CACxB,aAAa,EAAE,8BAA8B,EAC7C,QAAQ,EAAE,QAAQ,GACjB,OAAO,CA4CT;AAED,qBAAa,MAAM,CAAC,CAAC,EAAE,CAAC,CAAE,SAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IAG7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAFrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAW;gBAEF,QAAQ,EAAE,MAAM;IAI7C,MAAM,CAAC,GAAG,EAAE,CAAC;IAYb,GAAG,CAAC,GAAG,EAAE,CAAC;IAKV,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;CAIrB"}
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MapLru = void 0;
3
4
  exports.filterData = filterData;
4
5
  exports.filterScript = filterScript;
5
6
  exports.filterNumByRange = filterNumByRange;
@@ -85,3 +86,30 @@ function filterCell(searchKeyLike, cellLike) {
85
86
  }
86
87
  return true;
87
88
  }
89
+ class MapLru extends Map {
90
+ constructor(capacity) {
91
+ super();
92
+ this.capacity = capacity;
93
+ this.lru = [];
94
+ }
95
+ access(key) {
96
+ const index = this.lru.indexOf(key);
97
+ if (index !== -1) {
98
+ this.lru.splice(index, 1);
99
+ }
100
+ this.lru.push(key);
101
+ if (this.lru.length > this.capacity) {
102
+ this.delete(this.lru[0]);
103
+ this.lru.shift();
104
+ }
105
+ }
106
+ get(key) {
107
+ this.access(key);
108
+ return super.get(key);
109
+ }
110
+ set(key, value) {
111
+ this.access(key);
112
+ return super.set(key, value);
113
+ }
114
+ }
115
+ exports.MapLru = MapLru;
@@ -3,6 +3,8 @@ import { HexLike } from "../../hex/index.js";
3
3
  import { ClientCollectableSearchKeyLike } from "../clientTypes.advanced.js";
4
4
  import { ClientCache } from "./cache.js";
5
5
  export declare class ClientCacheMemory extends ClientCache {
6
+ private readonly maxCells;
7
+ private readonly maxTxs;
6
8
  /**
7
9
  * OutPoint => [isLive, Cell | OutPoint]
8
10
  */
@@ -11,6 +13,7 @@ export declare class ClientCacheMemory extends ClientCache {
11
13
  * TX Hash => Transaction
12
14
  */
13
15
  private readonly knownTransactions;
16
+ constructor(maxCells?: number, maxTxs?: number);
14
17
  markUsable(...cellLikes: (CellLike | CellLike[])[]): Promise<void>;
15
18
  markUnusable(...outPointLikes: (OutPointLike | OutPointLike[])[]): Promise<void>;
16
19
  clear(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/client/cache/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,QAAQ,EAER,YAAY,EACZ,WAAW,EACX,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAW,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,8BAA8B,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC,qBAAa,iBAAkB,SAAQ,WAAW;IAChD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CASR;IAEd;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAuC;IAEnE,UAAU,CAAC,GAAG,SAAS,EAAE,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IASlE,YAAY,CAChB,GAAG,aAAa,EAAE,CAAC,YAAY,GAAG,YAAY,EAAE,CAAC,EAAE,GAClD,OAAO,CAAC,IAAI,CAAC;IAcV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB,SAAS,CACd,OAAO,EAAE,8BAA8B,GACtC,cAAc,CAAC,IAAI,CAAC;IAYjB,OAAO,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAS9D,UAAU,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAMxD,kBAAkB,CACtB,GAAG,YAAY,EAAE,CAAC,eAAe,GAAG,eAAe,EAAE,CAAC,EAAE,GACvD,OAAO,CAAC,IAAI,CAAC;IAMV,cAAc,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAKrE,WAAW,CAAC,GAAG,KAAK,EAAE,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAWtE"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/client/cache/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,QAAQ,EAER,YAAY,EACZ,WAAW,EACX,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAW,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,8BAA8B,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC,qBAAa,iBAAkB,SAAQ,WAAW;IAY9C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAZzB;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IAEnD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA8B;gBAG7C,QAAQ,SAAM,EACd,MAAM,SAAM;IAQzB,UAAU,CAAC,GAAG,SAAS,EAAE,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IASlE,YAAY,CAChB,GAAG,aAAa,EAAE,CAAC,YAAY,GAAG,YAAY,EAAE,CAAC,EAAE,GAClD,OAAO,CAAC,IAAI,CAAC;IAcV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKrB,SAAS,CACd,OAAO,EAAE,8BAA8B,GACtC,cAAc,CAAC,IAAI,CAAC;IAajB,OAAO,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAS9D,UAAU,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAMxD,kBAAkB,CACtB,GAAG,YAAY,EAAE,CAAC,eAAe,GAAG,eAAe,EAAE,CAAC,EAAE,GACvD,OAAO,CAAC,IAAI,CAAC;IAMV,cAAc,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAKrE,WAAW,CAAC,GAAG,KAAK,EAAE,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAWtE"}
@@ -6,16 +6,12 @@ const index_js_2 = require("../../hex/index.js");
6
6
  const cache_js_1 = require("./cache.js");
7
7
  const memory_advanced_js_1 = require("./memory.advanced.js");
8
8
  class ClientCacheMemory extends cache_js_1.ClientCache {
9
- constructor() {
10
- super(...arguments);
11
- /**
12
- * OutPoint => [isLive, Cell | OutPoint]
13
- */
14
- this.cells = new Map();
15
- /**
16
- * TX Hash => Transaction
17
- */
18
- this.knownTransactions = new Map();
9
+ constructor(maxCells = 512, maxTxs = 256) {
10
+ super();
11
+ this.maxCells = maxCells;
12
+ this.maxTxs = maxTxs;
13
+ this.cells = new memory_advanced_js_1.MapLru(this.maxCells);
14
+ this.knownTransactions = new memory_advanced_js_1.MapLru(this.maxTxs);
19
15
  }
20
16
  async markUsable(...cellLikes) {
21
17
  cellLikes.flat().forEach((cellLike) => {
@@ -37,18 +33,18 @@ class ClientCacheMemory extends cache_js_1.ClientCache {
37
33
  });
38
34
  }
39
35
  async clear() {
40
- for (const val of this.cells.values()) {
41
- val[0] = undefined;
42
- }
36
+ this.cells.clear();
37
+ this.knownTransactions.clear();
43
38
  }
44
39
  async *findCells(keyLike) {
45
- for (const [isLive, cell] of this.cells.values()) {
40
+ for (const [key, [isLive, cell]] of this.cells.entries()) {
46
41
  if (!isLive) {
47
42
  continue;
48
43
  }
49
44
  if (!(0, memory_advanced_js_1.filterCell)(keyLike, cell)) {
50
45
  continue;
51
46
  }
47
+ this.cells.access(key);
52
48
  yield cell.clone();
53
49
  }
54
50
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckb-ccc/core",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Core of CCC - CKBer's Codebase",
5
5
  "author": "Hanssen0 <hanssen0@hanssen0.com>",
6
6
  "license": "MIT",
@@ -8,6 +8,15 @@ import {
8
8
  } from "../clientTypes.advanced.js";
9
9
  import { ClientIndexerSearchKey } from "../clientTypes.js";
10
10
 
11
+ // [isLive, Cell | OutPoint]
12
+ export type CellRecord =
13
+ | [
14
+ false,
15
+ Pick<Cell, "outPoint"> & Partial<Pick<Cell, "cellOutput" | "outputData">>,
16
+ ]
17
+ | [true, Cell]
18
+ | [undefined, Cell];
19
+
11
20
  export function filterData(
12
21
  dataLike: HexLike,
13
22
  filterLike: HexLike | undefined,
@@ -132,3 +141,33 @@ export function filterCell(
132
141
 
133
142
  return true;
134
143
  }
144
+
145
+ export class MapLru<K, V> extends Map<K, V> {
146
+ private readonly lru: K[] = [];
147
+
148
+ constructor(private readonly capacity: number) {
149
+ super();
150
+ }
151
+
152
+ access(key: K) {
153
+ const index = this.lru.indexOf(key);
154
+ if (index !== -1) {
155
+ this.lru.splice(index, 1);
156
+ }
157
+ this.lru.push(key);
158
+ if (this.lru.length > this.capacity) {
159
+ this.delete(this.lru[0]);
160
+ this.lru.shift();
161
+ }
162
+ }
163
+
164
+ get(key: K) {
165
+ this.access(key);
166
+ return super.get(key);
167
+ }
168
+
169
+ set(key: K, value: V) {
170
+ this.access(key);
171
+ return super.set(key, value);
172
+ }
173
+ }
@@ -6,30 +6,31 @@ import {
6
6
  Transaction,
7
7
  TransactionLike,
8
8
  } from "../../ckb/index.js";
9
- import { HexLike, hexFrom } from "../../hex/index.js";
9
+ import { hexFrom, HexLike } from "../../hex/index.js";
10
10
  import { ClientCollectableSearchKeyLike } from "../clientTypes.advanced.js";
11
11
  import { ClientCache } from "./cache.js";
12
- import { filterCell } from "./memory.advanced.js";
12
+ import { CellRecord, filterCell, MapLru } from "./memory.advanced.js";
13
13
 
14
14
  export class ClientCacheMemory extends ClientCache {
15
15
  /**
16
16
  * OutPoint => [isLive, Cell | OutPoint]
17
17
  */
18
- private readonly cells: Map<
19
- string,
20
- | [
21
- false,
22
- Pick<Cell, "outPoint"> &
23
- Partial<Pick<Cell, "cellOutput" | "outputData">>,
24
- ]
25
- | [true, Cell]
26
- | [undefined, Cell]
27
- > = new Map();
18
+ private readonly cells: MapLru<string, CellRecord>;
28
19
 
29
20
  /**
30
21
  * TX Hash => Transaction
31
22
  */
32
- private readonly knownTransactions: Map<string, Transaction> = new Map();
23
+ private readonly knownTransactions: MapLru<string, Transaction>;
24
+
25
+ constructor(
26
+ private readonly maxCells = 512,
27
+ private readonly maxTxs = 256,
28
+ ) {
29
+ super();
30
+
31
+ this.cells = new MapLru<string, CellRecord>(this.maxCells);
32
+ this.knownTransactions = new MapLru<string, Transaction>(this.maxTxs);
33
+ }
33
34
 
34
35
  async markUsable(...cellLikes: (CellLike | CellLike[])[]): Promise<void> {
35
36
  cellLikes.flat().forEach((cellLike) => {
@@ -57,15 +58,14 @@ export class ClientCacheMemory extends ClientCache {
57
58
  }
58
59
 
59
60
  async clear(): Promise<void> {
60
- for (const val of this.cells.values()) {
61
- val[0] = undefined;
62
- }
61
+ this.cells.clear();
62
+ this.knownTransactions.clear();
63
63
  }
64
64
 
65
65
  async *findCells(
66
66
  keyLike: ClientCollectableSearchKeyLike,
67
67
  ): AsyncGenerator<Cell> {
68
- for (const [isLive, cell] of this.cells.values()) {
68
+ for (const [key, [isLive, cell]] of this.cells.entries()) {
69
69
  if (!isLive) {
70
70
  continue;
71
71
  }
@@ -73,6 +73,7 @@ export class ClientCacheMemory extends ClientCache {
73
73
  continue;
74
74
  }
75
75
 
76
+ this.cells.access(key);
76
77
  yield cell.clone();
77
78
  }
78
79
  }