Skip to content

Commit

Permalink
Merge pull request #133 from primea/chunker
Browse files Browse the repository at this point in the history
added chunking for code stored in the state
  • Loading branch information
wanderer authored Jul 27, 2017
2 parents 6723a3a + 88bcb9d commit d2f195c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 4 deletions.
31 changes: 28 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ const Message = require('primea-message')
const Kernel = require('./kernel.js')
const Scheduler = require('./scheduler.js')
const DFSchecker = require('./dfsChecker.js')

const ROOT_ID = 'zdpuAm6aTdLVMUuiZypxkwtA7sKm7BWERy8MPbaCrFsmiyzxr'
const chunk = require('chunk')

module.exports = class Hypervisor {
/**
Expand All @@ -19,6 +18,9 @@ module.exports = class Hypervisor {
this.state = state
this._containerTypes = {}
this._nodesToCheck = new Set()

this.ROOT_ID = 'zdpuAm6aTdLVMUuiZypxkwtA7sKm7BWERy8MPbaCrFsmiyzxr'
this.MAX_DATA_BYTES = 65533
}

/**
Expand Down Expand Up @@ -57,11 +59,22 @@ module.exports = class Hypervisor {
async _loadInstance (id) {
const state = await this.graph.get(this.state, id)
const container = this._containerTypes[state.type]
let code

// checks if the code stored in the state is an array and that the elements
// are merkle link
if (state.code && state.code[0]['/']) {
await this.graph.tree(state.code, 1)
code = state.code.map(a => a['/']).reduce((a, b) => a + b)
} else {
code = state.code
}

// create a new kernel instance
const kernel = new Kernel({
hypervisor: this,
state: state,
code: code,
container: container,
id: id
})
Expand Down Expand Up @@ -115,6 +128,10 @@ module.exports = class Hypervisor {
type: type
}

if (message.data.length) {
state.code = message.data
}

// save the container in the state
await this.graph.set(this.state, idHash, state)
// create the container instance
Expand All @@ -123,6 +140,14 @@ module.exports = class Hypervisor {
// send the intialization message
await instance.initialize(message)

if (state.code && state.code.length > this.MAX_DATA_BYTES) {
state.code = chunk(state.code, this.MAX_DATA_BYTES).map(chk => {
return {
'/': chk
}
})
}

return instance
}

Expand All @@ -134,7 +159,7 @@ module.exports = class Hypervisor {
*/
async createStateRoot (ticks) {
await this.scheduler.wait(ticks)
const unlinked = await DFSchecker(this.graph, this.state, ROOT_ID, this._nodesToCheck)
const unlinked = await DFSchecker(this.graph, this.state, this.ROOT_ID, this._nodesToCheck)
unlinked.forEach(id => {
delete this.state[id]
})
Expand Down
1 change: 1 addition & 0 deletions kernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module.exports = class Kernel {
*/
constructor (opts) {
this.state = opts.state
this.code = opts.code
this.hypervisor = opts.hypervisor
this.id = opts.id
this.container = new opts.container.Constructor(this, opts.container.args)
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@
"dependencies": {
"binary-search-insert": "^1.0.3",
"bn.js": "^4.11.6",
"chunk": "0.0.2",
"ipld-graph-builder": "1.2.2",
"primea-abstract-container": "0.0.1",
"primea-abstract-container": "0.0.2",
"primea-message": "0.0.1"
},
"devDependencies": {
Expand Down
15 changes: 15 additions & 0 deletions tests/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const tape = require('tape')
const IPFS = require('ipfs')
const AbstractContainer = require('primea-abstract-container')
const Message = require('primea-message')
const Hypervisor = require('../')

// start ipfs
Expand Down Expand Up @@ -1071,4 +1072,18 @@ node.on('ready', () => {
rootContainer.send(portRef1, message)
rootContainer.ports.bind('response', rPort)
})

tape('large code size', async t => {
t.plan(1)
const content = Buffer.from(new ArrayBuffer(1000000))
class testVMContainer extends BaseContainer {
run () {}
}

const hypervisor = new Hypervisor(node.dag)
hypervisor.registerContainer('test', testVMContainer)
await hypervisor.createInstance('test', new Message({data: content}))
const instance = await hypervisor.getInstance(hypervisor.ROOT_ID)
t.equals(content.length, instance.code.length)
})
})

0 comments on commit d2f195c

Please sign in to comment.