Skip to content

Commit 7458c7c

Browse files
committed
feat: implement HybridSet class and createHybridSet function
1 parent 12c7f1f commit 7458c7c

File tree

3 files changed

+160
-0
lines changed

3 files changed

+160
-0
lines changed

src/perf/createHybridMap.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,27 @@
11
type Primitive = string | number | symbol | boolean | null | undefined
22
type KeyType = object | Primitive
33

4+
/**
5+
* HybridMap 是一个支持对象和原始类型(如字符串、数字、布尔值等)作为 key 的 Map 实现。
6+
* - 对象类型的 key 使用 WeakMap 存储,原始类型的 key 使用 Map 存储。
7+
* - 这样既可以用对象做 key,也可以用字符串、数字等做 key,且对象 key 不会阻止垃圾回收。
8+
* - 不支持遍历和 size 属性,因为 WeakMap 无法遍历。
9+
*
10+
* 示例用法:
11+
* ```ts
12+
* const map = createHybridMap<any, string>([[{}, 'obj'], ['a', 'str']])
13+
* map.set(123, 'num')
14+
* map.set({}, 'another obj')
15+
* ```
16+
*/
417
export class HybridMap<K extends KeyType, V> {
518
private objectStore: WeakMap<object, V>
619
private primitiveStore: Map<Primitive, V>
720

21+
/**
22+
* 构造函数,可选初始化 entries
23+
* @param entries 初始键值对数组
24+
*/
825
constructor(entries?: readonly (readonly [K, V])[] | null) {
926
this.objectStore = new WeakMap()
1027
this.primitiveStore = new Map()
@@ -15,10 +32,16 @@ export class HybridMap<K extends KeyType, V> {
1532
}
1633
}
1734

35+
/** 判断 key 是否为 object 类型 */
1836
private isObjectKey(key: K): key is Record<any, any> {
1937
return typeof key === 'object' && key !== null
2038
}
2139

40+
/**
41+
* 设置键值对
42+
* @param key 键
43+
* @param value 值
44+
*/
2245
set(key: K, value: V): this {
2346
if (this.isObjectKey(key)) {
2447
this.objectStore.set(key, value)
@@ -29,6 +52,10 @@ export class HybridMap<K extends KeyType, V> {
2952
return this
3053
}
3154

55+
/**
56+
* 获取指定 key 的值
57+
* @param key 键
58+
*/
3259
get(key: K): V | undefined {
3360
if (this.isObjectKey(key)) {
3461
return this.objectStore.get(key as object)
@@ -38,6 +65,10 @@ export class HybridMap<K extends KeyType, V> {
3865
}
3966
}
4067

68+
/**
69+
* 判断是否存在指定 key
70+
* @param key 键
71+
*/
4172
has(key: K): boolean {
4273
if (this.isObjectKey(key)) {
4374
return this.objectStore.has(key as object)
@@ -47,6 +78,10 @@ export class HybridMap<K extends KeyType, V> {
4778
}
4879
}
4980

81+
/**
82+
* 删除指定 key
83+
* @param key 键
84+
*/
5085
delete(key: K): boolean {
5186
if (this.isObjectKey(key)) {
5287
return this.objectStore.delete(key as object)
@@ -56,48 +91,68 @@ export class HybridMap<K extends KeyType, V> {
5691
}
5792
}
5893

94+
/** 清空所有 key */
5995
clear(): void {
6096
this.primitiveStore.clear()
6197
this.objectStore = new WeakMap()
6298
}
6399

100+
/** 不支持 size 属性,因 WeakMap 无法遍历 */
64101
get size(): number {
65102
throw new Error(
66103
'HybridMap does not support size due to WeakMap limitations.',
67104
)
68105
}
69106

107+
/** 不支持 forEach,因 WeakMap 无法遍历 */
70108
forEach(): void {
71109
throw new Error(
72110
'HybridMap does not support forEach due to WeakMap limitations.',
73111
)
74112
}
75113

114+
/** 不支持 keys 迭代,因 WeakMap 无法遍历 */
76115
keys() {
77116
throw new Error(
78117
'HybridMap does not support iteration due to WeakMap limitations.',
79118
)
80119
}
81120

121+
/** 不支持 values 迭代,因 WeakMap 无法遍历 */
82122
values() {
83123
throw new Error(
84124
'HybridMap does not support iteration due to WeakMap limitations.',
85125
)
86126
}
87127

128+
/** 不支持 entries 迭代,因 WeakMap 无法遍历 */
88129
entries() {
89130
throw new Error(
90131
'HybridMap does not support iteration due to WeakMap limitations.',
91132
)
92133
}
93134

135+
/** 不支持迭代器,因 WeakMap 无法遍历 */
94136
[Symbol.iterator]() {
95137
throw new Error(
96138
'HybridMap does not support iteration due to WeakMap limitations.',
97139
)
98140
}
99141
}
100142

143+
/**
144+
* createHybridMap 是 HybridMap 的工厂函数。
145+
* 用于创建支持对象和原始类型作为 key 的 Map 实例。
146+
* @param entries 可选的初始键值对数组
147+
* @returns HybridMap 实例
148+
*
149+
* 示例用法:
150+
* ```ts
151+
* const map = createHybridMap<any, string>([[{}, 'obj'], ['a', 'str']])
152+
* map.set(123, 'num')
153+
* map.set({}, 'another obj')
154+
* ```
155+
*/
101156
export function createHybridMap<K extends KeyType, V>(
102157
entries?: readonly (readonly [K, V])[] | null,
103158
): HybridMap<K, V> {

src/perf/createHybridSet.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
type Primitive = string | number | symbol | boolean | null | undefined
2+
type KeyType = object | Primitive
3+
4+
/**
5+
* HybridSet 是一个支持对象和原始类型(如字符串、数字、布尔值等)作为元素的 Set 实现。
6+
* - 对象类型的元素使用 WeakSet 存储,原始类型的元素使用 Set 存储。
7+
* - 这样既可以用对象做元素,也可以用字符串、数字等做元素,且对象元素不会阻止垃圾回收。
8+
* - 不支持遍历和 size 属性,因为 WeakSet 无法遍历。
9+
*
10+
* 示例用法:
11+
* ```ts
12+
* const set = createHybridSet<any>([{}, 'a', 123])
13+
* set.add('b')
14+
* set.add({})
15+
* ```
16+
*/
17+
export class HybridSet<T extends KeyType> {
18+
private objectStore: WeakSet<object>
19+
private primitiveStore: Set<Primitive>
20+
21+
/**
22+
* 构造函数,可选初始化 values
23+
* @param values 初始元素数组
24+
*/
25+
constructor(values?: readonly T[] | null) {
26+
this.objectStore = new WeakSet()
27+
this.primitiveStore = new Set()
28+
if (values) {
29+
for (const v of values) {
30+
this.add(v)
31+
}
32+
}
33+
}
34+
35+
/** 判断元素是否为 object 类型 */
36+
private isObjectKey(key: T): key is Record<any, any> {
37+
return typeof key === 'object' && key !== null
38+
}
39+
40+
/**
41+
* 添加元素
42+
* @param value 元素
43+
*/
44+
add(value: T): this {
45+
if (this.isObjectKey(value)) {
46+
this.objectStore.add(value)
47+
}
48+
else {
49+
this.primitiveStore.add(value as Primitive)
50+
}
51+
return this
52+
}
53+
54+
/**
55+
* 判断是否存在指定元素
56+
* @param value 元素
57+
*/
58+
has(value: T): boolean {
59+
if (this.isObjectKey(value)) {
60+
return this.objectStore.has(value)
61+
}
62+
else {
63+
return this.primitiveStore.has(value as Primitive)
64+
}
65+
}
66+
67+
/**
68+
* 删除指定元素
69+
* @param value 元素
70+
*/
71+
delete(value: T): boolean {
72+
if (this.isObjectKey(value)) {
73+
return this.objectStore.delete(value)
74+
}
75+
else {
76+
return this.primitiveStore.delete(value as Primitive)
77+
}
78+
}
79+
80+
/** 清空所有元素 */
81+
clear(): void {
82+
this.primitiveStore.clear()
83+
this.objectStore = new WeakSet()
84+
}
85+
}
86+
87+
/**
88+
* createHybridSet 是 HybridSet 的工厂函数。
89+
* 用于创建支持对象和原始类型作为元素的 Set 实例。
90+
* @param values 可选的初始元素数组
91+
* @returns HybridSet 实例
92+
*
93+
* 示例用法:
94+
* ```ts
95+
* const set = createHybridSet<any>([{}, 'a', 123])
96+
* set.add('b')
97+
* set.add({})
98+
* ```
99+
*/
100+
export function createHybridSet<T extends KeyType>(
101+
values?: readonly T[] | null,
102+
): HybridSet<T> {
103+
return new HybridSet(values)
104+
}

src/perf/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ export * from './useRic'
1111
export * from './once'
1212
export * from './createChunk'
1313
export * from './createHybridMap'
14+
export * from './createHybridSet'

0 commit comments

Comments
 (0)