Skip to content

Commit

Permalink
- RefGatherer now operates on entries not nodes, so theoretically, ba…
Browse files Browse the repository at this point in the history
…ckend can examine and prefetch the required part of graph in-depth
  • Loading branch information
Nickolay Platonov committed Oct 7, 2010
1 parent f9eefec commit 1b52e07
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 88 deletions.
3 changes: 1 addition & 2 deletions Components.JS
Expand Up @@ -57,8 +57,6 @@ COMPONENTS = {
"KiokuJS.Backend.Feature.Update",

"KiokuJS.Backend",
"KiokuJS.Backend.Hash",


"KiokuJS.Collapser",
"KiokuJS.Linker",
Expand All @@ -70,6 +68,7 @@ COMPONENTS = {

"Test" : [
"+Core",
"KiokuJS.Backend.Hash",

"KiokuJS.Test.Person",
"KiokuJS.Test.Person.Hobby",
Expand Down
10 changes: 2 additions & 8 deletions lib/KiokuJS/Backend.js
Expand Up @@ -59,23 +59,17 @@ Class('KiokuJS.Backend', {
decodePacket : function (packet) {
var scope = this.newScope()

var nodes = {}

Joose.A.each(scope.decodeEntries(packet.entries), function (node) {
nodes[ node.ID ] = node
})

var linker = new KiokuJS.Linker({
scope : scope,

nodes : nodes
entries : packet.entries
})

linker.animateNodes()

var objects = {}

Joose.O.each(packet.customIDs, function (value, id) {
Joose.A.each(packet.customIDs, function (id) {
objects[ id ] = scope.idToObject(id)
})

Expand Down
19 changes: 6 additions & 13 deletions lib/KiokuJS/Backend/Hash.js
Expand Up @@ -25,14 +25,12 @@ Class('KiokuJS.Backend.Hash', {

if (docs[ id ]) return docs[ id ]

throw new KiokuJS.Exception.LookUp({ id : id, backendName : this.meta.name })
})

var serializer = this.serializer
throw new KiokuJS.Exception.LookUp({ id : id, backendName : this.meta.name })

}, this)

var entries = Joose.A.map(strings, function (string) {
return serializer.deserialize(string)
})

var entries = Joose.A.map(strings, this.deserialize, this)

var CONTINUE = this.getCONTINUE()

Expand All @@ -45,12 +43,7 @@ Class('KiokuJS.Backend.Hash', {
insert : function (entries, mode) {
var docs = this.docs

var serializer = this.serializer

var strings = Joose.A.map(entries, function (entry) {
return serializer.serialize(entry)
})

var strings = Joose.A.map(entries, this.serialize, this)

Joose.A.each(entries, function (entry, index) {

Expand Down
78 changes: 46 additions & 32 deletions lib/KiokuJS/Linker.js
Expand Up @@ -7,28 +7,50 @@ Class('KiokuJS.Linker', {


has : {
scope : { required : true },
scope : {
required : true,
handles : 'decodeEntries'
},

entries : Joose.I.Object,

nodes : Joose.I.Object
nodes : {
lazy : function () {
return this.decodeEntries(this.entries)
}
}
},


methods : {

animateNodes : function () {
var scope = this.scope

KiokuJS.Linker.Expander.expandNodes(this.nodes, this.scope)
BUILD : function (config) {
var entries = config.entries

Joose.O.each(this.nodes, function (node, id) {
if (entries instanceof Array) {
var entriesByID = {}

if (node.isFirstClass()) scope.pinNode(node)
})
Joose.A.each(entries, function (entry) {
entriesByID[ entry.ID ] = entry
})

config.entries = entriesByID
}

return config
},


filterIDs : function (ids) {
animateNodes : function () {
var scope = this.scope
var nodes = this.getNodes()

KiokuJS.Linker.Expander.expandNodes(nodes, this.scope)

Joose.O.each(nodes, function (node, id) {

if (node.isFirstClass()) scope.pinNode(node)
})
}
},

Expand All @@ -51,47 +73,39 @@ Class('KiokuJS.Linker', {

backend.get(idsToFetch, scope).andThen(function (entries) {

var nodes = scope.decodeEntries(entries)

var newNodes = []
var newEntries = []

// filter the nodes returned from backend to only the new ones
// filter the entries returned from backend to only the new ones
// (which don't already have corresponding object in the scope)
// this should allow backends to pre-fetch references (potentially
// with extra nodes)
Joose.A.each(nodes, function (node) {
// with extra entries)
Joose.A.each(entries, function (entry) {

var nodeID = node.ID
var entryID = entry.ID

// some node was returned repeatedly
if (me.nodes[ nodeID ]) return
// some entry was returned repeatedly
if (me.entries[ entryID ]) return


var oldNode = scope.idToNode(nodeID)

if (!oldNode || shallowLevel > 0) {
if (!scope.idPinned(entryID) || shallowLevel > 0) {

me.nodes[ nodeID ] = node

newNodes.push(node)
me.entries[ entryID ] = entry

if (oldNode) node.consumeOldNode(oldNode)
newEntries.push(entry)
}
})


var notFetchedIds = []

Joose.A.each(scope.gatherReferences(newNodes), function (refID) {
if (me.nodes[ refID ]) return
Joose.A.each(scope.gatherReferences(newEntries), function (refID) {
if (me.entries[ refID ]) return

if (!scope.idPinned(refID) || shallowLevel == 2) notFetchedIds.push(refID)
})

if (notFetchedIds.length)
me.materialize(notFetchedIds, shallowLevel == 2 ? 2 : 0).now()
else
me.prefetchClasses(me.nodes).andThen(function () {
else
me.prefetchClasses(me.getNodes()).andThen(function () {

me.animateNodes()

Expand Down
4 changes: 4 additions & 0 deletions lib/KiokuJS/Linker/Expander.js
Expand Up @@ -16,6 +16,10 @@ Class('KiokuJS.Linker.Expander', {
visitNode : function (node) {
var scope = this.scope

var oldNode = scope.idToNode(node.ID)

if (oldNode) node.consumeOldNode(oldNode)

if (node.isLive())
node.clearInstance()
else
Expand Down
4 changes: 2 additions & 2 deletions lib/KiokuJS/Linker/RefGatherer.js
Expand Up @@ -12,8 +12,8 @@ Class('KiokuJS.Linker.RefGatherer', {

methods : {

visitJooseInstance : function (object, className) {
if (object instanceof KiokuJS.Reference && object.type != 'lazy') this.references[ object.ID ] = true
visitObject : function (object, className) {
if (object.$ref && object.type != 'lazy') this.references[ object.$ref ] = true

return this.SUPERARG(arguments)
}
Expand Down
3 changes: 2 additions & 1 deletion lib/KiokuJS/Node.js
Expand Up @@ -169,9 +169,10 @@ Class('KiokuJS.Node', {
consumeOldNode : function (oldNode) {
this.object = oldNode.object

this.isRoot = oldNode.isRoot
// this.isRoot = oldNode.isRoot seems this will be returned from DB in entry anyway

// XXX also copy `intrinsic, extrinsic, immutable and lazy` ?
// seems it will be recalculated during collapsing anyway?
},


Expand Down
33 changes: 13 additions & 20 deletions lib/KiokuJS/Scope.js
Expand Up @@ -25,13 +25,13 @@ Class('KiokuJS.Scope', {
nodesByID : Joose.I.Object,

encoder : {
handles : [ 'encodeNodes' ],
handles : 'encodeNodes',
init : Joose.I.FutureClass('KiokuJS.Collapser.Encoder')
},
decoder : Joose.I.FutureClass('KiokuJS.Linker.Decoder'),

gatherer : {
handles : [ 'gatherReferences' ],
handles : 'gatherReferences',
init : Joose.I.FutureClass('KiokuJS.Linker.RefGatherer')
}
},
Expand Down Expand Up @@ -204,10 +204,10 @@ Class('KiokuJS.Scope', {

Joose.A.each(nodes, this.pinNode, this)

var customIDs = {}
var customIDs = []

Joose.O.each(wIDs, function (object, id) {
customIDs[ id ] = true
customIDs.push(id)
})

return {
Expand Down Expand Up @@ -377,34 +377,27 @@ Class('KiokuJS.Scope', {
animatePacket : function (packet) {
var me = this

var nodes = {}

Joose.A.each(this.decodeEntries(packet.entries), function (node) {
nodes[ node.ID ] = node
var linker = new KiokuJS.Linker({
scope : this,
entries : packet.entries // entries will be converted from Array to Object (by ID)
})

var entries = linker.entries
var notFetchedRefs = []

var notFetchedRefs = []

Joose.A.each(this.gatherReferences(nodes), function (refID) {
if (nodes[ refID ]) return
Joose.A.each(this.gatherReferences(entries), function (refID) {
if (entries[ refID ]) return

if (!me.idPinned(refID)) notFetchedRefs.push(refID)
})


var linker = new KiokuJS.Linker({
scope : this,

nodes : nodes
})


linker.link(notFetchedRefs, 0).andThen(function () {

var objects = {}

Joose.O.each(packet.customIDs, function (value, id) {
Joose.A.each(packet.customIDs, function (id) {
objects[ id ] = me.idToObject(id)
})

Expand Down
3 changes: 3 additions & 0 deletions lib/KiokuJS/Test/Fixture/AnimatePacket.js
Expand Up @@ -65,6 +65,9 @@ Class('KiokuJS.Test.Fixture.AnimatePacket', {

var newScope = handle.newScope()

//======================================================================================================================================================================================================================================================
t.diag('Animating packet')

newScope.animatePacket(this.packet).andThen(function (customIDs, IDs) {

var test3 = customIDs.test3
Expand Down
16 changes: 7 additions & 9 deletions t/090_gatherer.t.js
Expand Up @@ -10,22 +10,20 @@ StartTest(function(t) {
//======================================================================================================================================================================================================================================================
t.diag('Setup')

var ref1 = new KiokuJS.Reference({
ID : '123'
})
var ref1 = {
$ref : '123'
}

var ref2 = new KiokuJS.Reference({
ID : '456'
})
var ref2 = {
$ref : '456'
}


var graph = {

foo : ref1,

bar : [ ref1, ref2 ],

$ref : 'baz'
bar : [ ref1, ref2 ]
}


Expand Down
2 changes: 1 addition & 1 deletion t/101_backend_packets.t.js
Expand Up @@ -52,7 +52,7 @@ StartTest(function(t) {

t.ok(packet.entries.length == 5, 'Packet contain 5 first-class entries')

t.ok(packet.customIDs.homer, 'Packet contain `homer` custom ID')
t.ok(packet.customIDs[0] == 'homer', 'Packet contain `homer` custom ID')

t.ok(packet.IDs.length == 1, 'Packet contain a single assigned ID')

Expand Down

0 comments on commit 1b52e07

Please sign in to comment.