Last active
January 12, 2020 18:48
-
-
Save YonatanKra/bc29b2d684a892a3321340d79e02c086 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
class PoolObject { | |
constructor(data) { | |
this.data = data; | |
this.nextFree = null; | |
this.previousFree = null; | |
this.free = true; | |
} | |
} | |
class Pool { | |
constructor(objCreator, objReseter, initialSize = 5000) { | |
this._pool = []; | |
this.objCreator = objCreator; | |
this.objReseter = objReseter; | |
for (let i = 0; i < initialSize; i++) { | |
this.addNewObject(this.newPoolObject()); | |
} | |
} | |
addNewObject(obj) { | |
this._pool.push(obj); | |
this.release(obj); | |
return obj; | |
} | |
release(poolObject) { | |
// flag as free | |
poolObject.free = true; | |
// set in the dequeue | |
poolObject.nextFree = null; | |
poolObject.previousFree = this.lastFree; | |
// if we had a last free, set the last free's next as the new poolObject | |
// otherwise, this is the first free! | |
if (poolObject.previousFree) { | |
this.lastFree.nextFree = poolObject; | |
} else { | |
this.nextFree = poolObject; | |
} | |
// set the new object as the last in the dequeue | |
this.lastFree = poolObject; | |
// reset the object if needed | |
this.objReseter(poolObject); | |
} | |
getFree() { | |
// if we have a free one, get it - otherwise create it | |
// if (!this.nextFree) { | |
// for (let i = 0; i < this._pool.length / 2; i++) { | |
// this.addNewObject(this.newPoolObject()); | |
// } | |
// } | |
const freeObject = this.nextFree ? this.nextFree : this.addNewObject(this.newPoolObject()); | |
// flag as used | |
freeObject.free = false; | |
// the next free is the object's next free | |
this.nextFree = freeObject.nextFree; | |
// if there's nothing afterwards, the lastFree is null as well | |
if (!this.nextFree) this.lastFree = null; | |
// return the now not free object | |
return freeObject; | |
} | |
newPoolObject() { | |
const data = this.objCreator(); | |
return new PoolObject(data, this.lastFree, this.nextFree); | |
} | |
releaseAll() { | |
this._pool.forEach(item => this.release(item)); | |
} | |
} | |
class Demo { | |
constructor(someVariable = null) { | |
this.counter = someVariable; | |
for (let i = 0; i < 150; i++) { | |
this[i] = i; | |
} | |
} | |
demoMethod(val) { | |
return val % 2; | |
} | |
demoMethod2(val) { | |
return val * 2; | |
} | |
demoMethod3(val) { | |
return val + 2; | |
} | |
demoMethod4(val) { | |
return val - 2; | |
} | |
} | |
const MAX_MESSAGES = 200; | |
const counters = { | |
deletions: 0, | |
additions: 0 | |
}; | |
const mockServer = new Worker("worker.js"); | |
mockServer.onmessage = function (e) { | |
// console.debug('Data received from server'); | |
const input = e.data; | |
handleInput(input); | |
}; | |
let pool; | |
let currState; | |
let dataSet = {}; | |
let inputHandling = 0; | |
function handleInput(input) { | |
if (currState === 'Pool') { | |
handleInputWithPool(input); | |
} else if (currState === 'NoPool') { | |
handleInputWithoutPool(input); | |
} | |
inputHandling++; | |
if (inputHandling === 1) { | |
// console.log('Finished filling up the dataSet for the first time'); | |
return; | |
} | |
counters.deletions += input.reduce((a,b) => a + (b.action ? 0 : 1), 0); | |
counters.additions += input.reduce((a,b) => a + (b.action ? 1 : 0), 0); | |
if (inputHandling === MAX_MESSAGES) { | |
console.log(`Totals: ${JSON.stringify(counters)}`); | |
} | |
} | |
function handleInputWithoutPool(input) { | |
for (let i = 0; i < input.length; i++) { | |
const id = input[i].payload.id; | |
switch (input[i].action) { | |
case 0: | |
// delete | |
delete dataSet[id]; | |
break; | |
case 1: | |
// create | |
dataSet[id] = new Demo(id); | |
break; | |
case 2: | |
// TODO::update | |
break; | |
} | |
} | |
} | |
function handleInputWithPool(input) { | |
let object; | |
for (let i = 0; i < input.length; i++) { | |
const id = input[i].payload.id; | |
switch (input[i].action) { | |
case 0: | |
// delete | |
object = dataSet[id]; | |
delete dataSet[id]; | |
if (object) { | |
pool.release(object); //TODO::expose the pool globally | |
} | |
break; | |
case 1: | |
object = pool.getFree(); | |
object.data.counter = i; | |
dataSet[id] = object; | |
break; | |
case 2: | |
// TODO::update | |
break; | |
} | |
} | |
} | |
function createAndDestroy() { | |
currState = 'NoPool'; | |
generalReset(); | |
} | |
function createWithAPool() { | |
currState = 'Pool'; | |
pool = new Pool(() => new Demo(null), | |
(item) => { | |
item.data.counter = null | |
}, | |
5000); | |
generalReset(); | |
} | |
function generalReset() { | |
counters.additions = counters.deletions = 0; | |
inputHandling = 0; | |
dataSet = {}; | |
if (pool) { | |
pool.releaseAll(); | |
} | |
mockServer.postMessage({MAX_MESSAGES}); | |
} | |
window.createAndDestroy = createAndDestroy; | |
window.createWithAPool = createWithAPool; | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const actions = { | |
0: 'DELETE', | |
1: 'CREATE', | |
2: 'UPDATE' | |
}; | |
const ids = []; | |
class Message { | |
constructor(action = 3, payload = {}) { | |
this.action = action; | |
this.payload = payload; | |
} | |
} | |
function setMessagePayload(message, id) { | |
message.payload.id = id ? id : Math.round(Math.random() * new Date().getTime()); | |
} | |
function getExistingID() { | |
return ids[Math.floor(Math.random()*(ids.length - 1))]; | |
} | |
function generateInput() { | |
const action = messages === 1 ? 1 : Math.random() < .49 ? 1 : 0; | |
const message = new Message(action); | |
switch (action) { | |
case 0: | |
//TODO::add the pool as global | |
setMessagePayload(message, getExistingID()); | |
entitiesCount--; | |
break; | |
case 1: | |
setMessagePayload(message); | |
ids.push(message.payload.id); | |
entitiesCount++; | |
break; | |
case 2: | |
setMessagePayload(message); | |
break; | |
} | |
return message; | |
} | |
let MAX_MESSAGES = 100; | |
const UPDATED_PER_MESSAGE = 1000; | |
const FIRST_ENTITIES_BULK = 5000; | |
let messages = Infinity; | |
let entitiesCount = 0; | |
setInterval(() => { | |
if (messages >= MAX_MESSAGES) return; | |
messages++; | |
const pushUpdate = new Array(messages === 1 ? FIRST_ENTITIES_BULK : UPDATED_PER_MESSAGE).fill(0).map(i => generateInput()); | |
postMessage(pushUpdate); | |
}, 200); | |
onmessage = function(e) { | |
if (messages < MAX_MESSAGES) { | |
console.log('Worker: Message from main script ignored'); | |
return; | |
} | |
MAX_MESSAGES = (e.data && e.data.MAX_MESSAGES) ? e.data.MAX_MESSAGES : 0; | |
console.log('Worker: Message received from main script'); | |
entitiesCount = 0; | |
messages = 0; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment