Skip to content

Instantly share code, notes, and snippets.

@createvibe
Created May 4, 2016 19:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save createvibe/78f079bf185909685bb54345eac36815 to your computer and use it in GitHub Desktop.
Save createvibe/78f079bf185909685bb54345eac36815 to your computer and use it in GitHub Desktop.
/**
* @constructor Creates a new memory manager for the provided array.
* @param {memory} An array to use as the backing memory.
*/
function MemoryManager(memory){
this.memory = memory;
this.allocated = {};
}
/**
* Available memory
* @type {Array}
*/
MemoryManager.prototype.memory = null;
/**
* Allocated memory blocks
* @type {Object} Hash of allocated blocks: {pointer: size}
*/
MemoryManager.prototype.allocated = null;
/**
* Allocates a block of memory of requested size.
* @param {number} size - The size of the block to allocate.
* @returns {number} A pointer which is the index of the first location in the allocated block.
* @throws If it is not possible to allocate a block of the requested size.
*/
MemoryManager.prototype.allocate = function(size){
var i,
idx,
diff,
lastIdx = 0,
lastIdxSize = 0,
pointer = 0,
pointers = Object.keys(this.allocated),
len = pointers.length;
for (i = 0; i < len; i++) {
// object key is the index the pointer block starts at
idx = new Number(pointers[i]);
// if this index > last index + size, check difference and see if we can reallocate
if (lastIdx + lastIdxSize + size <= idx) {
diff = idx - (lastIdx + lastIdxSize);
if (diff >= size) {
pointer = lastIdx + lastIdxSize;
break;
}
}
// save last index
lastIdx = idx;
lastIdxSize = this.allocated[idx];
// pointer is current index + current index block size (non inclusive)
pointer = idx + this.allocated[idx];
}
if (pointer + size > this.memory.length) {
throw new Error('Unable to allocate memory with size: ' + size);
}
this.allocated[pointer] = size;
return pointer;
};
/**
* Releases a previously allocated block of memory.
* @param {number} pointer - The pointer to the block to release.
* @throws If the pointer does not point to an allocated block.
*/
MemoryManager.prototype.release = function(pointer){
if (!(pointer in this.allocated)) {
throw new Error('Cannot release unallocated block at position ' + pointer);
}
this.memory.splice.apply(this.memory, [pointer, this.allocated[pointer]].concat(new Array(this.allocated[pointer])));
delete this.allocated[pointer];
};
/**
* Reads the value at the location identified by pointer
* @param {number} pointer - The location to read.
* @returns {number} The value at that location.
* @throws If pointer is in unallocated memory.
*/
MemoryManager.prototype.read = function(pointer){
var idx;
for (idx in this.allocated) {
if (pointer < idx + this.allocated[idx]) {
return this.memory[pointer];
}
}
throw new Error('Cannot read from unallocated memory at position ' + pointer);
};
/**
* Writes a value to the location identified by pointer
* @param {number} pointer - The location to write to.
* @param {number} value - The value to write.
* @throws If pointer is in unallocated memory.
*/
MemoryManager.prototype.write = function(pointer, value){
var idx;
for (idx in this.allocated) {
if (pointer < idx + this.allocated[idx]) {
this.memory[pointer] = value;
return;
}
}
throw new Error('Cannot write to unallocated memory at position ' + pointer);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment