Created
May 4, 2016 19:00
-
-
Save createvibe/78f079bf185909685bb54345eac36815 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
/** | |
* @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