Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: cache string and tuple representations #275

Merged
merged 3 commits into from
Sep 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import varint from 'varint'
import { concat as uint8ArrayConcat } from 'uint8arrays/concat'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
import type { Protocol } from './protocols-table.js'
import type { StringTuple, Tuple } from './index.js'

/**
* string -> [[str name, str addr]... ]
Expand Down Expand Up @@ -50,7 +51,7 @@ export function stringToStringTuples (str: string) {
/**
* [[str name, str addr]... ] -> string
*/
export function stringTuplesToString (tuples: Array<[number, string?]>) {
export function stringTuplesToString (tuples: StringTuple[]) {
const parts: string[] = []
tuples.map((tup) => {
const proto = protoFromTuple(tup)
Expand All @@ -67,7 +68,7 @@ export function stringTuplesToString (tuples: Array<[number, string?]>) {
/**
* [[str name, str addr]... ] -> [[int code, Uint8Array]... ]
*/
export function stringTuplesToTuples (tuples: Array<string[] | string>): Array<[number, Uint8Array?]> {
export function stringTuplesToTuples (tuples: Array<string[] | string>): Tuple[] {
return tuples.map((tup) => {
if (!Array.isArray(tup)) {
tup = [tup]
Expand All @@ -85,7 +86,7 @@ export function stringTuplesToTuples (tuples: Array<string[] | string>): Array<[
*
* [[int code, Uint8Array]... ] -> [[int code, str addr]... ]
*/
export function tuplesToStringTuples (tuples: Array<[number, Uint8Array?]>): Array<[number, string?]> {
export function tuplesToStringTuples (tuples: Tuple[]): StringTuple[] {
return tuples.map(tup => {
const proto = protoFromTuple(tup)
if (tup[1] != null) {
Expand All @@ -98,7 +99,7 @@ export function tuplesToStringTuples (tuples: Array<[number, Uint8Array?]>): Arr
/**
* [[int code, Uint8Array ]... ] -> Uint8Array
*/
export function tuplesToBytes (tuples: Array<[number, Uint8Array?]>) {
export function tuplesToBytes (tuples: Tuple[]) {
return fromBytes(uint8ArrayConcat(tuples.map((tup) => {
const proto = protoFromTuple(tup)
let buf = Uint8Array.from(varint.encode(proto.code))
Expand All @@ -122,7 +123,7 @@ export function sizeForAddr (p: Protocol, addr: Uint8Array | number[]) {
}
}

export function bytesToTuples (buf: Uint8Array): Array<[number, Uint8Array?]> {
export function bytesToTuples (buf: Uint8Array): Tuple[] {
const tuples: Array<[number, Uint8Array?]> = []
let i = 0
while (i < buf.length) {
Expand Down
30 changes: 24 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export type MultiaddrInput = string | Multiaddr | Uint8Array | null

export interface Resolver { (addr: Multiaddr, options?: AbortOptions): Promise<string[]> }

export type Tuple = [number, Uint8Array?]

export type StringTuple = [number, string?]

export interface AbortOptions {
signal?: AbortSignal
}
Expand Down Expand Up @@ -137,7 +141,7 @@ export interface Multiaddr {
* // [ [ 4, <Buffer 7f 00 00 01> ], [ 6, <Buffer 0f a1> ] ]
* ```
*/
tuples: () => Array<[number, Uint8Array?]>
tuples: () => Tuple[]

/**
* Returns a tuple of string/number parts
Expand All @@ -150,7 +154,7 @@ export interface Multiaddr {
* // [ [ 4, '127.0.0.1' ], [ 6, '4001' ] ]
* ```
*/
stringTuples: () => Array<[number, string?]>
stringTuples: () => StringTuple[]

/**
* Encapsulates a Multiaddr in another Multiaddr
Expand Down Expand Up @@ -396,6 +400,9 @@ export function isMultiaddr (value: any): value is Multiaddr {
*/
class DefaultMultiaddr implements Multiaddr {
public bytes: Uint8Array
private _string?: string
private _tuples?: Tuple[]
private _stringTuples?: StringTuple[]

[symbol]: boolean = true

Expand Down Expand Up @@ -429,7 +436,11 @@ class DefaultMultiaddr implements Multiaddr {
}

toString () {
return codec.bytesToString(this.bytes)
if (this._string == null) {
this._string = codec.bytesToString(this.bytes)
}

return this._string
}

toJSON () {
Expand Down Expand Up @@ -495,12 +506,19 @@ class DefaultMultiaddr implements Multiaddr {
}

tuples (): Array<[number, Uint8Array?]> {
return codec.bytesToTuples(this.bytes)
if (this._tuples == null) {
this._tuples = codec.bytesToTuples(this.bytes)
}

return this._tuples
}

stringTuples (): Array<[number, string?]> {
const t = codec.bytesToTuples(this.bytes)
return codec.tuplesToStringTuples(t)
if (this._stringTuples == null) {
this._stringTuples = codec.tuplesToStringTuples(this.tuples())
}

return this._stringTuples
}

encapsulate (addr: MultiaddrInput): Multiaddr {
Expand Down
6 changes: 3 additions & 3 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -695,13 +695,13 @@ describe('helpers', () => {
const relay = relayTCP.encapsulate('/p2p/QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6/p2p-circuit')
const target = multiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
const original = relay.encapsulate(target)
expect(original.decapsulateCode(421)).to.eql(relay)
expect(relay.decapsulateCode(421)).to.eql(relayTCP)
expect(original.decapsulateCode(421).toJSON()).to.eql(relay.toJSON())
expect(relay.decapsulateCode(421).toJSON()).to.eql(relayTCP.toJSON())
})

it('ignores missing codes', () => {
const tcp = multiaddr('/ip4/0.0.0.0/tcp/8080')
expect(tcp.decapsulateCode(421)).to.eql(tcp)
expect(tcp.decapsulateCode(421).toJSON()).to.eql(tcp.toJSON())
})
})

Expand Down