Skip to content
This repository has been archived by the owner on Jan 11, 2019. It is now read-only.

Commit

Permalink
Add initial RelaxedArrayNode implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Phil Pluckthun committed Jan 1, 2017
1 parent 7fecdca commit 12d3dd5
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 3 deletions.
5 changes: 2 additions & 3 deletions src/persistentVector/ArrayNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,12 @@ export default class ArrayNode<T> {

set(key: number, value: T, owner?: Object): ArrayNode<T> {
const index = maskHash(key, this.level)
if (index >= this.content.length) {
const oldSubNode = this.content[index]
if (!oldSubNode) {
return this
}

const oldSubNode = this.content[index]
const subNode = oldSubNode.set(key, value, owner)

if (oldSubNode === subNode) {
return this
}
Expand Down
80 changes: 80 additions & 0 deletions src/persistentVector/RelaxedArrayNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import Node from './Node'
import { Option } from '../constants'
import { replaceValue } from '../util/array'
import { maskHash } from '../util/bitmap'
import createSizeTable from './util/createSizeTable'

function findTableIndex(
key: number,
level: number,
sizeTable: number[]
): number {
let index = maskHash(key, level)
while (sizeTable[index] <= key) {
index = index + 1
}

return index
}

export default class RelaxedArrayNode<T> {
level: number // NOTE: This can only be >= 1
content: Node<T>[]
sizeTable: number[]
size: number
owner?: Object

constructor(
level: number,
content: Node<T>[],
size: number,
owner?: Object
) {
this.level = level
this.content = content
this.sizeTable = createSizeTable(content)
this.size = size
this.owner = owner
}

get(key: number, notSetVal?: T): Option<T> {
if (key >= this.size) {
return notSetVal
}

const index = findTableIndex(key, this.level, this.sizeTable)
const subNode = this.content[index]
const newKey = index === 0 ? index : key - this.sizeTable[index - 1]

return subNode.get(newKey, notSetVal)
}

set(key: number, value: T, owner?: Object): RelaxedArrayNode<T> {
if (key >= this.size) {
return this
}

const index = findTableIndex(key, this.level, this.sizeTable)
const oldSubNode = this.content[index]
const newKey = index === 0 ? index : key - this.sizeTable[index - 1]

const subNode = oldSubNode.set(newKey, value, owner)
if (oldSubNode === subNode) {
return this
}

if (owner && owner === this.owner) {
this.content[index] = subNode
return this
}

const content = replaceValue(this.content, index, subNode)

return new RelaxedArrayNode<T>(
this.level,
content,
this.size,
owner
)
}
}
17 changes: 17 additions & 0 deletions src/persistentVector/util/createSizeTable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Node from '../Node'

function createSizeTable(content: Node<any>[]): number[] {
const length = content.length
const sizeTable = new Array(length)

let sum = 0
for (let i = 0; i < length; i++) {
const node = content[i]
sum = sum + node.size
sizeTable[i] = sum
}

return sizeTable
}

export default createSizeTable

0 comments on commit 12d3dd5

Please sign in to comment.