Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
dai-shi committed Oct 12, 2024
1 parent e9a0510 commit bd6cbf3
Showing 1 changed file with 28 additions and 30 deletions.
58 changes: 28 additions & 30 deletions src/vanilla/utils/proxyMap-indexMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ const maybeProxify = (x: any) => (typeof x === 'object' ? proxy({ x }).x : x)
const isProxy = (x: any) => proxyStateMap.has(x)

type InternalProxyObject<K, V> = Map<K, V> & {
data: Array<[K, V | undefined]>
data: Array<[K, V] | undefined>
nextIndex: number
size: number
toJSON: () => Map<K, V>
}

const MIN_DATA_SIZE = 1000

export function proxyMap<K, V>(entries?: Iterable<[K, V]> | undefined | null) {
const data: Array<[K, V]> = []
const initialData: Array<[K, V] | undefined> = new Array(MIN_DATA_SIZE).fill(
undefined,
)
let initialNextIndex = 0
const indexMap = new Map<K, number>()
const emptyIndexes: number[] = []
let nextIndex = 0

if (entries !== null && typeof entries !== 'undefined') {
if (typeof entries[Symbol.iterator] !== 'function') {
Expand All @@ -25,56 +28,51 @@ export function proxyMap<K, V>(entries?: Iterable<[K, V]> | undefined | null) {
for (const [k, v] of entries) {
const key = maybeProxify(k)
const value = maybeProxify(v)
indexMap.set(key, data.length)
data[nextIndex++] = [key, value]
indexMap.set(key, initialNextIndex)
initialData[initialNextIndex++] = [key, value]
}
}

const vObject: InternalProxyObject<K, V> = {
data,
nextIndex,
data: initialData,
nextIndex: initialNextIndex,
get size() {
return indexMap.size
},
get(key: K) {
const k = maybeProxify(key)
if (!indexMap.has(k) && !isProxy(this)) {
const index = indexMap.get(k)
if (index === undefined && !isProxy(this)) {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this.data.length
this.nextIndex
}
if (indexMap.has(k)) {
const index = indexMap.get(k)!
if (this.data[index] !== undefined) {
return this.data[index]![1]
}
if (index !== undefined) {
return this.data[index]![1]
}
return undefined
},
has(key: K) {
const k = maybeProxify(key)
if (!indexMap.has(k) && !isProxy(this)) {
const exists = indexMap.has(k)
if (!exists && !isProxy(this)) {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this.data.length
this.nextIndex
}
return indexMap.has(k)
return exists
},
set(key: K, value: V) {
if (!isProxy(this)) {
throw new Error('Cannot perform mutations on a snapshot')
}
const k = maybeProxify(key)
const v = maybeProxify(value)
let index = indexMap.get(k)
const index = indexMap.get(k)
if (index === undefined) {
index = emptyIndexes.length ? emptyIndexes.pop()! : nextIndex++
indexMap.set(k, index)
}
const pair = this.data[index]
if (pair) {
pair[1] = v
const i = emptyIndexes.length ? emptyIndexes.pop()! : this.nextIndex++
indexMap.set(k, i)
this.data[i] = [k, v]
} else {
// Allocate a new array only if necessary
this.data[index] = [k, v]
this.data[index]![1] = v
}
return this
},
Expand All @@ -85,8 +83,7 @@ export function proxyMap<K, V>(entries?: Iterable<[K, V]> | undefined | null) {
const k = maybeProxify(key)
const index = indexMap.get(k)
if (index !== undefined) {
const index = indexMap.get(k)!
delete this.data[index]
this.data[index] = undefined
indexMap.delete(k)
emptyIndexes.push(index)
return true
Expand All @@ -98,7 +95,8 @@ export function proxyMap<K, V>(entries?: Iterable<[K, V]> | undefined | null) {
throw new Error('Cannot perform mutations on a snapshot')
}
indexMap.clear()
this.data.splice(0)
this.data.splice(MIN_DATA_SIZE).fill(undefined)
this.nextIndex = 0
emptyIndexes.splice(0)
},
forEach(cb: (value: V, key: K, map: Map<K, V>) => void) {
Expand Down

0 comments on commit bd6cbf3

Please sign in to comment.