Skip to content

Commit

Permalink
feat: compress assetIds
Browse files Browse the repository at this point in the history
  • Loading branch information
woodenfurniture committed Dec 20, 2024
1 parent 4fbd84f commit 1a79883
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 4 deletions.
16 changes: 15 additions & 1 deletion packages/utils/src/assetData/decodeAssetData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,22 @@ import { FIELDS } from './constants'
import { getBaseAsset } from './getBaseAsset'
import type { EncodedAssetData, FieldToType } from './types'

const decodeAssetId = (encodedAssetId: string, assetIdPrefixes: string[]) => {
// Performance sensitive. `lastIndexOf` + `substring` faster than `split`
const colonIndex = encodedAssetId.lastIndexOf(':')
const prefixIdx = Number(encodedAssetId.substring(0, colonIndex))
const assetReference = encodedAssetId.substring(colonIndex + 1)

// Performance sensitive. String concatenation faster than template literal
return assetIdPrefixes[prefixIdx] + ':' + assetReference
}

export const decodeAssetData = (encodedAssetData: EncodedAssetData) => {
const { sortedAssetIds, encodedAssets } = encodedAssetData
const { assetIdPrefixes, encodedAssetIds, encodedAssets } = encodedAssetData

const sortedAssetIds = encodedAssetIds.map(encodedAssetId =>
decodeAssetId(encodedAssetId, assetIdPrefixes),
)

const assetData = encodedAssets.reduce<Record<AssetId, Asset>>((acc, encodedAsset, idx) => {
const assetId = sortedAssetIds[idx]
Expand Down
36 changes: 34 additions & 2 deletions packages/utils/src/assetData/encodeAssetData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,35 @@ import { assertUnreachable } from '../assertUnreachable'
import { FIELDS } from './constants'
import type { EncodedAsset, EncodedAssetData, Field, FieldToType } from './types'

const encodeAssetIds = (sortedAssetIds: AssetId[]) => {
const assetIdPrefixes: string[] = []
const encodedAssetIds = []
for (const assetId of sortedAssetIds) {
// `indexOf` + `substring` faster than `split`
const colonIndex = assetId.lastIndexOf(':')
const prefix = assetId.substring(0, colonIndex)
const assetReference = assetId.substring(colonIndex + 1)

const prefixIdx = (() => {
const prefixIdx = assetIdPrefixes.indexOf(prefix)

if (prefixIdx !== -1) {
return prefixIdx
} else {
assetIdPrefixes.push(prefix)
return assetIdPrefixes.length - 1
}
})()

encodedAssetIds.push(`${prefixIdx}:${assetReference}`)
}

return {
assetIdPrefixes,
encodedAssetIds,
}
}

const encodeField = <F extends Field>(
field: F,
assetIdToAssetIdx: Record<AssetId, number>,
Expand Down Expand Up @@ -38,21 +67,24 @@ export const encodeAssetData = (
sortedAssetIds: AssetId[],
assetsById: AssetsById,
): EncodedAssetData => {
const { assetIdPrefixes, encodedAssetIds } = encodeAssetIds(sortedAssetIds)

const assetIdToAssetIdx = sortedAssetIds.reduce<Record<AssetId, number>>((acc, val, idx) => {
acc[val] = idx
return acc
}, {})

const encodedAssets: EncodedAsset[] = []
for (let i = 0; i < sortedAssetIds.length; i++) {
for (let i = 0; i < encodedAssetIds.length; i++) {
const assetId = sortedAssetIds[i]
const asset = assetsById[assetId]
const record = FIELDS.map(field => encodeField(field, assetIdToAssetIdx, asset)) as EncodedAsset
encodedAssets.push(record)
}

return {
sortedAssetIds,
assetIdPrefixes,
encodedAssetIds,
encodedAssets,
}
}
3 changes: 2 additions & 1 deletion packages/utils/src/assetData/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type EncodedAsset = [
]

export type EncodedAssetData = {
sortedAssetIds: AssetId[]
assetIdPrefixes: string[]
encodedAssetIds: string[]
encodedAssets: EncodedAsset[]
}

0 comments on commit 1a79883

Please sign in to comment.