Comparing version 1.0.1 to 1.0.2
@@ -85,2 +85,3 @@ // File: block_file.js | ||
// | ||
BlockFile.Props = Props | ||
BlockFile.BlockFile = BlockFile | ||
@@ -102,3 +103,4 @@ BlockFile.Handle = Handle | ||
var metaProps = u.defaults(u.clone(metaProps_), Props.defaultProps._metaProps) | ||
var metaProps = u.defaults( u.clone(metaProps_) | ||
, Props.defaultProps.metaProps()) | ||
@@ -168,3 +170,6 @@ Props.assertValidMetaProps(metaProps) | ||
function BlockFile_open(filename, metaProps) { | ||
metaProps = u.defaults(u.clone(metaProps||{}), Props.defaultProps._metaProps) | ||
if ( u.isUndefined(metaProps) ) | ||
metaProps = Props.defaultProps.metaProps() | ||
else | ||
metaProps = u.defaults(u.clone(metaProps), Props.defaultProps.metaProps()) | ||
@@ -275,3 +280,3 @@ var stat, fd, bf | ||
//calculate number of segments from filesize | ||
calcNumSegs = Math.ceil( fileSize / this.props.maxSegSize ) | ||
calcNumSegs = Math.ceil( fileSize / this.props.maxSegSize() ) | ||
if (!(calcNumSegs == 0 || Handle.isValidSegNum(calcNumSegs-1, this.props))) { | ||
@@ -360,3 +365,3 @@ err = new Error(format("Invalid calculated number of Segments %d" | ||
, nextSegNum = self.segments.length | ||
, buffer = new Buffer(this.props.fsmSize) | ||
, buffer = new Buffer(this.props.fsmSize()) | ||
@@ -372,3 +377,3 @@ buffer.fill(0xff) //completely empty | ||
BlockFile.prototype._calcSegOff = function(segNum) { | ||
return BlockFile.MD_HDRSIZE + ( segNum * this.props.maxSegSize ) | ||
return BlockFile.MD_HDRSIZE + ( segNum * this.props.maxSegSize() ) | ||
} | ||
@@ -379,4 +384,4 @@ | ||
return this._calcSegOff(segNum) + | ||
this.props.segHdrSize + | ||
(blkNum * this.props.blockSize) | ||
this.props.segHdrSize() + | ||
(blkNum * this.props.blockSize()) | ||
} | ||
@@ -394,7 +399,7 @@ | ||
fsmBuf = new Buffer(this.props.fsmSize) | ||
fsmBuf = new Buffer(this.props.fsmSize()) | ||
var segOffset = self._calcSegOff(segNum) | ||
, fileOffsetFsmPri = segOffset + self.props.fsmOffsetPrimary | ||
, fileOffsetFsmSec = segOffset + self.props.fsmOffsetSecondary | ||
, fileOffsetFsmPri = segOffset + self.props.fsmOffsetPrimary() | ||
, fileOffsetFsmSec = segOffset + self.props.fsmOffsetSecondary() | ||
@@ -453,4 +458,4 @@ return pfs.read( self.fd | ||
var segOffset = self._calcSegOff(segNum) | ||
, fileOffsetFsmPri = segOffset + self.props.fsmOffsetPrimary | ||
, fileOffsetFsmSec = segOffset + self.props.fsmOffsetSecondary | ||
, fileOffsetFsmPri = segOffset + self.props.fsmOffsetPrimary() | ||
, fileOffsetFsmSec = segOffset + self.props.fsmOffsetSecondary() | ||
@@ -544,3 +549,3 @@ return pfs.write( self.fd | ||
function BlockFile__load(hdl) { | ||
var buffer = new Buffer(this.props.blockSize*(1+hdl.spanNum)) | ||
var buffer = new Buffer(this.props.blockSize() *(1+hdl.spanNum)) | ||
, blkOff = this._calcBlkOff(hdl.segNum, hdl.blkNum) | ||
@@ -556,4 +561,3 @@ , doneNS = bfStats.get("tt_load ns").start() | ||
readp.then( doneNS ) | ||
//DEL:readp.then(function(){ doneNS() }) | ||
readp.then(function(){ doneNS() }) //need to call doneNS w/o arguments | ||
@@ -578,3 +582,3 @@ loadp = readp.spread(function(bytesRead, buffer){ | ||
numBlks = Math.ceil( buffer.length / this.props.blockSize ) | ||
numBlks = Math.ceil( buffer.length / this.props.blockSize() ) | ||
@@ -590,4 +594,3 @@ hdl = hdl || this._reserve(numBlks) | ||
writep.then(doneNS) | ||
//DEL:writep.then(function(){ doneNS() }) | ||
writep.then(function(){ doneNS() }) //need to call doneNS w/o arguments | ||
@@ -594,0 +597,0 @@ storep = writep.spread(function(bytesWritten, buf){ |
@@ -37,6 +37,6 @@ | ||
assert.equal(freeBlockMap.length, this.props.numBlkNums) | ||
assert.equal(freeBlockMap.length, this.props.numBlkNums()) | ||
this.spans = [] | ||
for (var g=this.props.minSpanNum; g<=this.props.maxSpanNum; g++) { | ||
for (var g=this.props.minSpanNum(); g<=this.props.maxSpanNum(); g++) { | ||
this.spans[g] = [ /* begBlkNum0, ..., begBlkNumN */ ] | ||
@@ -49,8 +49,8 @@ } | ||
for ( var curBlockNum = this.props.minBlkNum; | ||
curBlockNum <= this.props.maxBlkNum; | ||
for ( var curBlockNum = this.props.minBlkNum(); | ||
curBlockNum <= this.props.maxBlkNum(); | ||
curBlockNum += 1 ) | ||
{ | ||
var free = freeBlockMap[curBlockNum] | ||
, curSpanNum = this.props.minSpanNum | ||
, curSpanNum = this.props.minSpanNum() | ||
, begBlkNum = curBlockNum | ||
@@ -61,3 +61,3 @@ | ||
while(1) { | ||
if (!free || curSpanNum >= this.props.maxSpanNum || curBlockNum >= this.props.maxBlkNum) { | ||
if (!free || curSpanNum >= this.props.maxSpanNum() || curBlockNum >= this.props.maxBlkNum()) { | ||
//capture | ||
@@ -123,6 +123,6 @@ this.spans[curSpanNum].push(begBlkNum) | ||
function NaiveFSM__alloc(reqSpanNum) { | ||
if (reqSpanNum === undefined) reqSpanNum = this.props.minSpanNum | ||
if (reqSpanNum === undefined) reqSpanNum = this.props.minSpanNum() | ||
var spanNum, begBlkNum | ||
for (spanNum = reqSpanNum; spanNum <= this.props.maxSpanNum; spanNum += 1) { | ||
for (spanNum = reqSpanNum; spanNum <= this.props.maxSpanNum(); spanNum += 1) { | ||
if (this.spans[spanNum].length > 0) { | ||
@@ -136,3 +136,3 @@ begBlkNum = this._delete(spanNum, 0) | ||
} | ||
if (spanNum > this.props.maxSpanNum) | ||
if (spanNum > this.props.maxSpanNum()) | ||
return undefined //no room available in FSM | ||
@@ -215,3 +215,3 @@ | ||
var begBlkNum2, spanNum2 | ||
while (spanNum > this.props.maxSpanNum) { | ||
while (spanNum > this.props.maxSpanNum()) { | ||
// note: spans are designated by (begBlkNum, spanNum) | ||
@@ -221,5 +221,5 @@ //ex span=(0,16) => span'=(0,0) & span2=(1,15) | ||
// span''=(0,0) & span2'=(1,15) | ||
spanNum -= this.props.maxSpanNum + 1 //16 | ||
spanNum -= this.props.maxSpanNum() + 1 //16 | ||
begBlkNum2 = begBlkNum+spanNum /*endBlkNum*/ + 1 | ||
spanNum2 = this.props.maxSpanNum | ||
spanNum2 = this.props.maxSpanNum() | ||
@@ -226,0 +226,0 @@ this._insert(begBlkNum2, spanNum2) |
@@ -8,2 +8,4 @@ | ||
//Props.WARN = false | ||
/* | ||
@@ -48,6 +50,6 @@ * bits #bits num value | ||
assert.ok(segNum % 1 === 0, format("segNum=%j not an Integer", segNum)) | ||
assert.ok( segNum >= props.minSegNum | ||
, format("segnum(%d) < MIN_SEGNUM(%d)", segNum, props.minSegNum ) ) | ||
assert.ok( segNum <= props.maxSegNum | ||
, format("segnum(%d) > MAX_SEGNUM(%d)", segNum, props.maxSegNum ) ) | ||
assert.ok( segNum >= props.minSegNum() | ||
, format("segnum(%d) < MIN_SEGNUM(%d)", segNum, props.minSegNum() ) ) | ||
assert.ok( segNum <= props.maxSegNum() | ||
, format("segnum(%d) > MAX_SEGNUM(%d)", segNum, props.maxSegNum() ) ) | ||
} | ||
@@ -65,8 +67,8 @@ | ||
assert.ok(blkNum % 1 === 0, format("blkNum(%j) not an Integer", blkNum)) | ||
assert.ok( blkNum >= props.minBlkNum | ||
assert.ok( blkNum >= props.minBlkNum() | ||
, format("blkNum(%d) < MIN_BLOCKNUM(%d)" | ||
, blkNum, props.minBlkNum) ) | ||
assert.ok( blkNum <= props.maxBlkNum | ||
, blkNum, props.minBlkNum()) ) | ||
assert.ok( blkNum <= props.maxBlkNum() | ||
, format("blkNum(%d) > MAX_BLOCKNUM(%d)" | ||
, blkNum, props.maxBlkNum) ) | ||
, blkNum, props.maxBlkNum()) ) | ||
} | ||
@@ -83,8 +85,8 @@ | ||
assert.ok(spanNum % 1 === 0, format("spanNum(%j) not an Integer", spanNum)) | ||
assert.ok( spanNum >= props.minSpanNum | ||
assert.ok( spanNum >= props.minSpanNum() | ||
, format("spanNum(%d) < MIN_SPANNUM(%d)" | ||
, spanNum, props.minSpanNum) ) | ||
assert.ok( spanNum <= props.maxSpanNum | ||
, spanNum, props.minSpanNum()) ) | ||
assert.ok( spanNum <= props.maxSpanNum() | ||
, format("spanNum(%d) > MAX_SPANNUM(%d)" | ||
, spanNum, props.maxSpanNum) ) | ||
, spanNum, props.maxSpanNum()) ) | ||
} | ||
@@ -99,3 +101,3 @@ | ||
props = props || Props.defaultProps | ||
return segNum % 1 === 0 && segNum >= props.minSegNum && segNum <= props.maxSegNum | ||
return segNum % 1 === 0 && segNum >= props.minSegNum() && segNum <= props.maxSegNum() | ||
} | ||
@@ -110,3 +112,3 @@ | ||
props = props || Props.defaultProps | ||
return blkNum % 1 === 0 && blkNum >= props.minBlkNum && blkNum <= props.maxBlkNum | ||
return blkNum % 1 === 0 && blkNum >= props.minBlkNum() && blkNum <= props.maxBlkNum() | ||
} | ||
@@ -121,3 +123,3 @@ | ||
props = props || Props.defaultProps | ||
return spanNum % 1 === 0 && spanNum >= props.minSpanNum && spanNum <= props.maxSpanNum | ||
return spanNum % 1 === 0 && spanNum >= props.minSpanNum() && spanNum <= props.maxSpanNum() | ||
} | ||
@@ -134,6 +136,7 @@ | ||
Handle.equals = function(a, b) { | ||
return a.props.equals(b.props) && | ||
a.segNum == b.segNum && | ||
a.blkNum == b.blkNum && | ||
a.spanNum == b.spanNum | ||
return a instanceof Handle && b instanceof Handle && | ||
a.props.equals(b.props) && | ||
a.segNum === b.segNum && | ||
a.blkNum === b.blkNum && | ||
a.spanNum === b.spanNum | ||
} | ||
@@ -159,5 +162,8 @@ | ||
Handle.prototype.encode = function(){ | ||
var value = this.segNum << this.segNumShift | | ||
this.blkNum << this.props.blkNumShift | | ||
this.spanNum << this.props.spanNumShift | ||
assert(this.props.numHandleBits == 32, "only support encoding 32 bit handles") | ||
var value = this.segNum << this.props.segNumShift() | | ||
this.blkNum << this.props.blkNumShift() | | ||
this.spanNum << this.props.spanNumShift() | ||
return value | ||
@@ -177,2 +183,3 @@ } | ||
props = props || Props.defaultProps | ||
assert(props.numHandleBits == 32, "only support encoding 32 bit handles") | ||
assert.equal(typeof hdlv, 'number') | ||
@@ -183,7 +190,7 @@ | ||
hdlv = hdlv & intMask //only use the bottom 32 bits | ||
var segNum = (hdlv & props.segNumMask) | ||
, blkNum = (hdlv & props.blkNumMask) >> props.blkNumShift | ||
, spanNum = (hdlv & props.spanNumMask) >> props.spanNumShift | ||
var segNum = (hdlv & props.segNumMask()) | ||
, blkNum = (hdlv & props.blkNumMask()) >> props.blkNumShift() | ||
, spanNum = (hdlv & props.spanNumMask()) >> props.spanNumShift() | ||
return new Handle(segNum, blkNum, spanNum) | ||
return new Handle(segNum, blkNum, spanNum, props) | ||
} | ||
@@ -198,6 +205,38 @@ | ||
Handle.prototype.toString = function(){ | ||
return this.segNum+"/"+this.blkNum+"/"+this.spanNum | ||
var metaPropsStr = JSON.stringify(this.props.metaProps()) | ||
return this.segNum+"/"+this.blkNum+"/"+this.spanNum+metaPropsStr | ||
} | ||
Handle.minStringLen = function(props){ | ||
var segNum = props.minSegNum() | ||
, blkNum = props.minBlkNum() | ||
, spanNum = props.minSpanNum() | ||
, hdl = new Handle(segNum, blkNum, spanNum, props) | ||
return hdl.toString().length | ||
} | ||
Handle.maxStringLen = function(props){ | ||
var segNum = props.maxSegNum() | ||
, blkNum = props.maxBlkNum() | ||
, spanNum = props.maxSpanNum() | ||
, hdl = new Handle(segNum, blkNum, spanNum, props) | ||
return hdl.toString().length | ||
} | ||
Handle.fromString = function(s){ | ||
var m = s.match(/^(\d+)\/(\d+)\/(\d+)(\{[^\}]+\})$/) | ||
, segNum = parseInt( m[1], 10) | ||
, blkNum = parseInt( m[2], 10) | ||
, spanNum = parseInt( m[3], 10) | ||
, metaProps = JSON.parse( m[4] ) | ||
assert( Array.isArray(m) | ||
, "string failed to match /^(\d+)\/(\d+)\/(\d+)(\{[^\}]+\})$/" ) | ||
var props = new Props(metaProps) | ||
, hdl = new Handle(segNum, blkNum, spanNum, props) | ||
return hdl | ||
} | ||
//THE END |
253
lib/props.js
@@ -20,16 +20,10 @@ | ||
//Utility functions | ||
var pow = Math.pow | ||
var utils = require('./utils') | ||
, log2 = utils.log2 | ||
, min = utils.min | ||
, max = utils.max | ||
, pow = Math.pow | ||
, ceil = Math.ceil | ||
, floor = Math.floor | ||
function log2(v) { | ||
var r = Math.log(v)/Math.LN2 | ||
//if v is event and the result is not an integer (ie fucked up double math), | ||
// then just round result to nearest integer. | ||
//basically Math.log(v)/Math.LN2 is getting the last bit of the fraction part | ||
// of the double-precision floting point number wrong (ie off by one). | ||
if (r%1 > 0 && r%1 <= 1.1368683772161603e-13) return Math.floor(r) | ||
return r | ||
} | ||
function requireBits(num) { return ceil(log2(num)) } | ||
@@ -54,3 +48,5 @@ function toBits(bytes) { return bytes*8 } | ||
var unsupported = u.difference(u.keys(metaProps), u.keys(defaultMetaProps)) | ||
assert(unsupported.length === 0, format("Unknown metaProps %j", unsupported)) | ||
//assert(unsupported.length === 0, format("Unknown metaProps %j", unsupported)) | ||
if (Props.WARN && unsupported.length > 0) | ||
console.warn("Warning: unsuported metaProps = %j", unsupported) | ||
@@ -62,100 +58,14 @@ Props.assertValidMetaProps( metaProps ) | ||
var properties = { | ||
_metaProps: | ||
{ value: metaProps } | ||
, blockSzBits : | ||
{ get: function(){ return metaProps.blockSzBits } | ||
//, set: function(v){ metaProps.blockSzBits = v } | ||
, enumerable: true } | ||
, fsmSzBits : | ||
{ get: function(){ return metaProps.fsmSzBits || metaProps.blockSzBits } | ||
//, set: function(v){ metaProps.fsmSzBits = v } | ||
, enumerable: true } | ||
//Handle structure properties | ||
, checkSumBits : | ||
{ get: function(){ return metaProps.checkSumBits } | ||
//, set: function(v){ metaProps.checkSumBits = v } | ||
, enumerable: true } | ||
, checkSumOffset: | ||
{ get: function(){ return metaProps.checkSumOffset } | ||
//, set: function(v){ metaProps.checkSumOffset = v } | ||
, enumerable: true } | ||
, numHandleBits: | ||
{ get: function(){ return metaProps.numHandleBits } | ||
//, set: function(v){ metaProps.numHandleBits = v } | ||
, enumerable: true } | ||
, spanNumBits : | ||
{ get: function(){ return metaProps.spanNumBits } | ||
//, set: function(v){ metaProps.spanNumBits = v } | ||
, enumerable: true } | ||
, segNumBits : | ||
{ get: function(){ | ||
return this.numHandleBits - this.spanNumBits - this.blkNumBits | ||
} | ||
, enumerable: true } | ||
, blockSize: | ||
{ get: function(){ return pow(2, this.blockSzBits) } | ||
, enumerable: true } | ||
, numBlkNums : | ||
{ get: function(){ return toBits(this.fsmSize) - this.checkSumBits } | ||
, enumerable: true } | ||
, minBlkNum: { value: 0, enumerable: true } | ||
, maxBlkNum : | ||
{ get: function(){ return this.numBlkNums-1 } | ||
, enumerable: true } | ||
, numSegNums : | ||
{ get: function(){ return pow(2, this.segNumBits) } | ||
, enumerable: true } | ||
, minSegNum: { value: 0, enumerable: true } | ||
, maxSegNum : | ||
{ get: function(){ return this.numSegNums-1 } | ||
, enumerable: true } | ||
, numSpanNums : | ||
{ get: function(){ return pow(2, this.spanNumBits) } | ||
, enumerable: true } | ||
, minSpanNum: { value: 0, enumerable: true } | ||
, maxSpanNum : | ||
{ get: function(){ return this.numSpanNums-1 } | ||
, enumerable: true } | ||
, segNumShift : { value: 0 } | ||
, segNumMask : | ||
{ get: function(){ return pow(2, this.segNumBits)-1 } | ||
, enumerable: true } | ||
, blkNumBits : | ||
{ get: function(){ return ceil(log2(this.numBlkNums)) } | ||
, enumerable: true } | ||
, blkNumShift : | ||
{ get: function(){ return this.segNumBits } | ||
, enumerable: true } | ||
, blkNumMask : | ||
{ get: function(){ return pow(2, this.blkNumBits)-1<<this.blkNumShift } | ||
, enumerable: true } | ||
, spanNumShift : | ||
{ get: function(){ return this.segNumBits+this.blkNumBits } | ||
, enumerable: true } | ||
, spanNumMask : | ||
{ get: function(){ return pow(2, this.spanNumBits)-1<<this.spanNumShift } | ||
, enumerable: true } | ||
, fsmSize : | ||
{ get: function(){ return pow(2, this.fsmSzBits) } | ||
, enumerable: true } | ||
, segHdrSize : | ||
{ get: function(){ return 2*this.fsmSize } | ||
, enumerable: true } | ||
, fsmOffsetPrimary: | ||
{ value: 0, enumerable: true } | ||
, fsmOffsetSecondary: | ||
{ get: function(){ return this.fsmSize } | ||
, enumerable: true } | ||
// , numBlksSeg //isn't that just numBlkNums | ||
, maxSegSize: | ||
{ get: function(){ return this.segHdrSize + this.numBlkNums*this.blockSize } | ||
, enumerable: true } | ||
// , fileHdrSize: | ||
// { get: function() { return 2 * this.blockSize } | ||
// , enumerable: true } | ||
// , mdOffsetPrimary: | ||
// { value: 0, enumerable: true } | ||
// , mdOffsetSecondary: | ||
// { get: function() { return this.blockSize } | ||
// , enumerable: true } | ||
blockSzBits : { value: metaProps.blockSzBits | ||
, enumerable: true } | ||
, fsmSzBits : { value: metaProps.fsmSzBits || metaProps.blockSzBits | ||
, enumerable: true } | ||
, checkSumBits : { value: metaProps.checkSumBits | ||
, enumerable: true } | ||
, checkSumOffset: { value: metaProps.checkSumOffset | ||
, enumerable: true } | ||
, numHandleBits : { value: metaProps.numHandleBits | ||
, enumerable: true } | ||
, spanNumBits : { value: metaProps.spanNumBits | ||
, enumerable: true } | ||
} //end: props properties object | ||
@@ -175,2 +85,4 @@ | ||
Props.WARN = true | ||
exports = module.exports = Props | ||
@@ -233,3 +145,3 @@ | ||
var not = u.difference(u.keys(metaProps), u.keys(defaultMetaProps)) | ||
assert(not.length == 0, format("these keys are NOT supported %j", not)) | ||
//assert(not.length == 0, format("these keys are NOT supported %j", not)) | ||
@@ -239,5 +151,2 @@ var req = u.difference(u.keys(defaultMetaProps), u.keys(metaProps)) | ||
//for (var p in defaultMetaProps) | ||
// assert(u.has(metaProps, p), format("metaProps does not have '%s'", p)) | ||
//numHandleBits | ||
@@ -247,3 +156,3 @@ assert(typeof metaProps.numHandleBits == 'number' | ||
assert(metaProps.numHandleBits == 32 || metaProps.numHandleBits == 64 | ||
, "numHandleBits is not 32 or 64") | ||
, "numHandleBits is not 32 or 64") | ||
@@ -311,21 +220,123 @@ //checkSumBits | ||
Props.prototype.maxNumBlks = function(){ | ||
return this.numSegNums * this.numBlkNums | ||
Props.prototype.metaProps = function(){ | ||
return { | ||
blockSzBits : this.blockSzBits | ||
, fsmSzBits : this.fsmSzBits | ||
, checkSumBits : this.checkSumBits | ||
, checkSumOffset: this.checkSumOffset | ||
, numHandleBits : this.numHandleBits | ||
, spanNumBits : this.spanNumBits | ||
} | ||
} | ||
Props.prototype.segNumBits = function(){ | ||
return this.numHandleBits - this.spanNumBits - this.blkNumBits() | ||
} | ||
Props.prototype.blockSize = function(){ | ||
return pow(2, this.blockSzBits) | ||
} | ||
Props.prototype.numBlkNums = function(){ | ||
return toBits(this.fsmSize()) - this.checkSumBits | ||
} | ||
Props.prototype.minBlkNum = function(){ | ||
return 0 | ||
} | ||
Props.prototype.maxBlkNum = function(){ | ||
return this.numBlkNums() - 1 + this.minBlkNum() | ||
} | ||
Props.prototype.numSegNums = function(){ | ||
return pow(2, this.segNumBits()) | ||
} | ||
Props.prototype.minSegNum = function(){ | ||
return 0 | ||
} | ||
Props.prototype.maxSegNum = function(){ | ||
return this.numSegNums() - 1 + this.minSegNum() | ||
} | ||
Props.prototype.numSpanNums = function(){ | ||
return pow(2, this.spanNumBits) | ||
} | ||
Props.prototype.minSpanNum = function(){ | ||
return 0 | ||
} | ||
Props.prototype.maxSpanNum = function(){ | ||
return this.numSpanNums() - 1 + this.minSpanNum() | ||
} | ||
Props.prototype.segNumShift = function(){ | ||
return 0 | ||
} | ||
Props.prototype.segNumMask = function(){ | ||
return pow(2, this.segNumBits()) - 1 //<< this.segNumShift() ?? | ||
} | ||
Props.prototype.blkNumBits = function(){ | ||
return ceil(log2(this.numBlkNums())) | ||
} | ||
Props.prototype.blkNumShift = function(){ | ||
return this.segNumBits() | ||
} | ||
Props.prototype.blkNumMask = function(){ | ||
return pow(2, this.blkNumBits()) - 1 << this.blkNumShift() | ||
} | ||
Props.prototype.spanNumShift = function(){ | ||
return this.segNumBits() + this.blkNumBits() | ||
} | ||
Props.prototype.spanNumMask = function(){ | ||
return pow(2, this.spanNumBits) - 1 << this.spanNumShift() | ||
} | ||
Props.prototype.fsmSize = function(){ | ||
return pow(2, this.fsmSzBits) | ||
} | ||
Props.prototype.fsmOffsetPrimary = function(){ | ||
return 0 | ||
} | ||
Props.prototype.fsmOffsetSecondary = function(){ | ||
return this.fsmSize() | ||
} | ||
Props.prototype.segHdrSize = function(){ | ||
return 2*this.fsmSize() | ||
} | ||
Props.prototype.maxSegSize = function(){ | ||
return this.numSegNums*((2*this.fsmSize)+(this.numBlkNums*this.blockSize)) | ||
return this.segHdrSize() + ( this.numBlkNums() * this.blockSize() ) | ||
} | ||
Props.prototype.maxFileSize = function(){ | ||
return this.numSegNums * this.maxSegSize() | ||
return this.numSegNums() * this.maxSegSize() | ||
} | ||
Props.prototype.maxDataSize = function(){ | ||
return this.numSegNums * this.numBlkNums * this.blockSize | ||
return this.numSegNums() * this.numBlkNums() * this.blockSize() | ||
} | ||
Props.prototype.toString = function(){ | ||
return JSON.stringify( this.metaProps() ) | ||
} | ||
Props.fromString = function(s){ | ||
return new Props( JSON.parse(s) ) | ||
} | ||
Props.defaultProps = new Props() | ||
// |
@@ -11,4 +11,4 @@ | ||
, utils = require('./utils') | ||
, bufferReadBit = utils.bufferReadBit | ||
, bufferWriteBit = utils.bufferWriteBit | ||
, readBit = utils.readBit | ||
, writeBit = utils.writeBit | ||
@@ -29,3 +29,3 @@ /** Constructor for Segment of BpTree file | ||
assert.ok( Buffer.isBuffer(buffer), "argument buffer is not a Buffer" ) | ||
assert.strictEqual(buffer.length, this.props.fsmSize) | ||
assert.strictEqual(buffer.length, this.props.fsmSize()) | ||
assert.equal(typeof fsmType, 'function', "argument fsmType is not a Function") | ||
@@ -38,4 +38,4 @@ | ||
this.freeBlockMap = [] | ||
for (var i = this.props.minBlkNum; i <= this.props.maxBlkNum; i++) { | ||
this.freeBlockMap[i] = bufferReadBit(buffer,16+i) | ||
for (var i = this.props.minBlkNum(); i <= this.props.maxBlkNum(); i++) { | ||
this.freeBlockMap[i] = readBit(buffer,16+i) | ||
} | ||
@@ -68,3 +68,3 @@ | ||
, fixedOffset = this.props.checkSumOffset + this.props.checkSumBits | ||
, bufv = bufferReadBit(this.buffer, fixedOffset + blkNum) | ||
, bufv = readBit(this.buffer, fixedOffset + blkNum) | ||
@@ -87,4 +87,4 @@ return fbmv | ||
this.freeBlockMap[blkNum] = v | ||
bufferWriteBit( this.buffer, fixedOffset + blkNum, v) | ||
//bufferWriteBit(this.buffer, 16+blkNum, v) | ||
writeBit( this.buffer, fixedOffset + blkNum, v) | ||
//writeBit(this.buffer, 16+blkNum, v) | ||
@@ -91,0 +91,0 @@ return this |
@@ -5,3 +5,2 @@ | ||
var assert = require('assert') | ||
, Props = require('./props') | ||
, crc16 = require('crc').buffer.crc16 | ||
@@ -12,3 +11,3 @@ , crc32 = require('crc').buffer.crc32 | ||
exports.printf = function(){ | ||
var printf = exports.printf = function(){ | ||
var args = Array.prototype.slice.call(arguments) | ||
@@ -20,3 +19,3 @@ args.unshift(process.stdout) | ||
exports.eprintf = function(){ | ||
var eprintf = exports.eprintf = function(){ | ||
var args = Array.prototype.slice.call(arguments) | ||
@@ -32,4 +31,48 @@ args.unshift(process.stderr) | ||
exports.xor = function xor(p,q) { return (p && !q) || (!p && q) } | ||
var isInt = exports.isInt = function isInt(x) { | ||
return typeof x == 'number' && x % 1 == 0 | ||
} | ||
var xor = exports.xor = function xor(p,q) { return (p && !q) || (!p && q) } | ||
var log2 = exports.log2 = function log2(v) { | ||
var r = Math.log(v)/Math.LN2 | ||
, rmod1 = r%1 | ||
if (rmod1 > 0 && rmod1 <= 1.1368683772161603e-13) return Math.floor(r) | ||
if (rmod1 < 0 && -rmod1 <= 2.2737367544323206e-13) return Math.ceil(r) | ||
return r | ||
} | ||
var log10 = exports.log10 = function log10(v) { | ||
var r = Math.log(v)/Math.LN10 | ||
, rmod1 = r%1 | ||
if (rmod1 > 0 && 1-rmod1 <= 5.684341886080802e-14) return Math.ceil(r) | ||
if (rmod1 < 0 && 1+rmod1 <= 5.684341886080802e-14) return Math.floor(r) | ||
//works to -310 but it is probably matching to much non integer solutions | ||
return r | ||
} | ||
var min = exports.min = function min(){ | ||
var minval = arguments[0] | ||
for (var i=1; i<arguments.length; i++) | ||
if (minval > arguments[i]) minval = arguments[i] | ||
return minval | ||
} | ||
var max = exports.max = function max(){ | ||
var maxval = arguments[0] | ||
for (var i=1; i<arguments.length; i++) | ||
if (maxval < arguments[i]) maxval = arguments[i] | ||
return maxval | ||
} | ||
var spanLength = exports.spanLength = function spanLength(spanNum) { | ||
return Math.pow(2, spanNum) | ||
} | ||
/** | ||
@@ -42,3 +85,3 @@ * Repeat a string N times. | ||
*/ | ||
exports.repeatStr = function(str, n) { | ||
var repeatst = exports.repeatStr = function(str, n) { | ||
var sd = "" | ||
@@ -60,3 +103,3 @@ , s2 = n > 0 ? str : "" | ||
*/ | ||
exports.bufferReadBit = function bufferReadBit(buffer, bit) { | ||
var readBit = exports.readBit = function readBit(buffer, bit) { | ||
var byt, off, num, res | ||
@@ -82,3 +125,3 @@ | ||
*/ | ||
exports.bufferWriteBit = function bufferWriteBit(buffer, bit, value) { | ||
var writeBit = exports.writeBit = function writeBit(buffer, bit, value) { | ||
var byt, off, num | ||
@@ -249,3 +292,2 @@ | ||
var readCRC = exports.readCRC = function(buffer, props){ | ||
props = props || Props.defaultProps | ||
switch (props.checkSumBits) { | ||
@@ -259,3 +301,2 @@ case 16: return buffer.readUInt16BE(props.checkSumOffset) | ||
var calculateCRC = exports.calculateCRC = function(buffer, props){ | ||
props = props || Props.defaultProps | ||
switch (props.checkSumBits) { | ||
@@ -269,3 +310,2 @@ case 16: return calculateCRC16(buffer, props.checkSumOffset) | ||
var signCRC = exports.signCRC = function(buffer, props){ | ||
props = props || Props.defaultProps | ||
switch (props.checkSumBits) { | ||
@@ -279,4 +319,3 @@ case 16: return signCRC16(buffer, props.checkSumOffset) | ||
var validateCRC = exports.validateCRC = function(buffer, props){ | ||
props = props || Props.defaultProps | ||
return readCRC(buffer, props) === calculateCRC(buffer, props) | ||
} |
{ | ||
"name" : "block-file" | ||
, "version" : "1.0.1" | ||
, "version" : "1.0.2" | ||
, "description" : "A library to read/write blocks from a file" | ||
@@ -15,2 +15,22 @@ , "keywords" : ["block", "buffer", "storage"] | ||
, "main" : "lib/block_file.js" | ||
, "files" : [ "package.json" | ||
, "README.md" | ||
, "lorem-ipsum.1k.txt" | ||
, "lorem-ipsum.4k.txt" | ||
, "lorem-ipsum.64k.txt" | ||
, "lib/package.json" | ||
, "lib/block_file.js" | ||
, "lib/fsm_naive.js" | ||
, "lib/handle.js" | ||
, "lib/props.js" | ||
, "lib/segment.js" | ||
, "lib/utils.js" | ||
, "lib/y-fs.js" | ||
, "test/00-basic.js" | ||
, "test/01-Handle.js" | ||
, "test/02-NaiveFSM.js" | ||
, "test/03-Segment.js" | ||
, "test/04-block-file.js" | ||
, "test/05-block-file-alt-props.js" | ||
] | ||
, "license" : "MIT" | ||
@@ -25,4 +45,5 @@ , "scripts" : { "test" : "mocha -R spec -s 1" } | ||
, "mocha" : "*" | ||
, "chai" : "*" } | ||
, "chai" : "*" | ||
, "printf" : "*" } | ||
, "engines" : { "node" : ">=0.4.0" } | ||
} |
@@ -14,5 +14,5 @@ /* global describe it */ | ||
it("should generate a binary value of 0", function(){ | ||
var hdl = new Handle( props.minSegNum | ||
, props.minBlkNum | ||
, props.minSpanNum ) | ||
var hdl = new Handle( props.minSegNum() | ||
, props.minBlkNum() | ||
, props.minSpanNum() ) | ||
expect(hdl.encode()).to.equal(0) | ||
@@ -24,11 +24,11 @@ }) | ||
it("should generate a binary value of 0xfffdffff>>0", function(){ | ||
var hdl = new Handle( props.maxSegNum | ||
, props.maxBlkNum | ||
, props.maxSpanNum ) | ||
// , expected = props.maxSegNum << props.segNumShift | | ||
// props.maxBlkNum << props.blkNumShift | | ||
// props.maxSpanNum << props.spanNumShift //-131073 | ||
var hdl = new Handle( props.maxSegNum() | ||
, props.maxBlkNum() | ||
, props.maxSpanNum() ) | ||
// , expected = props.maxSegNum() << props.segNumShift() | | ||
// props.maxBlkNum() << props.blkNumShift() | | ||
// props.maxSpanNum() << props.spanNumShift() //-131073 | ||
// , expected = 0xfffdffff //4294836223 uint32 | ||
, expected = 0xfffdffff>>00 //-131073 int32 | ||
// , expected = 0xfffdffff>>>00 //-131073 uint32 | ||
, expected = 0xfffdffff>>0 //-131073 int32 | ||
// , expected = 0xfffdffff>>>0 //-131073 uint32 | ||
@@ -35,0 +35,0 @@ expect(hdl.encode()).to.equal(expected) |
@@ -17,3 +17,3 @@ /* global describe it */ | ||
for (i=0; i <= props.maxBlkNum; i+=1) fbm[i] = true | ||
for (i=0; i <= props.maxBlkNum(); i+=1) fbm[i] = true | ||
@@ -32,5 +32,5 @@ describe("Constructor", function(){ | ||
describe("fsm.alloc props.minSpanNum", function(){ | ||
describe("fsm.alloc props.minSpanNum()", function(){ | ||
it(".alloc()", function(){ | ||
blkNum = fsm.alloc(props.minSpanNum) | ||
blkNum = fsm.alloc(props.minSpanNum()) | ||
expect(blkNum).to.be.a('number') | ||
@@ -40,5 +40,5 @@ }) | ||
describe("fsm.free props.minSpanNum", function(){ | ||
describe("fsm.free props.minSpanNum()", function(){ | ||
it("fsm.free above allocated object", function(){ | ||
fsm.free(blkNum, props.minSpanNum) | ||
fsm.free(blkNum, props.minSpanNum()) | ||
}) | ||
@@ -53,9 +53,9 @@ it("fsm is equal to original NaiveFSM object", function(){ | ||
describe("fsm.alloc x3 props.minSpanNum, then fsm.free [0,1,2]", function(){ | ||
describe("fsm.alloc x3 props.minSpanNum(), then fsm.free [0,1,2]", function(){ | ||
var blkNum = [] | ||
describe("fsm.alloc x3 props.minSpanNum", function(){ | ||
describe("fsm.alloc x3 props.minSpanNum()", function(){ | ||
it(".alloc() blkNum[0..2]", function(){ | ||
for (var i=0; i<3; i++) { | ||
blkNum[i] = fsm.alloc(props.minSpanNum) | ||
blkNum[i] = fsm.alloc(props.minSpanNum()) | ||
expect(blkNum[i]).to.be.a('number') | ||
@@ -68,7 +68,7 @@ } | ||
it("fsm.free blkNum[0]" | ||
, function(){ fsm.free(blkNum[0], props.minSpanNum) }) | ||
, function(){ fsm.free(blkNum[0], props.minSpanNum()) }) | ||
it("fsm.free blkNum[1]" | ||
, function(){ fsm.free(blkNum[1], props.minSpanNum) }) | ||
, function(){ fsm.free(blkNum[1], props.minSpanNum()) }) | ||
it("fsm.free blkNum[2]" | ||
, function(){ fsm.free(blkNum[2], props.minSpanNum) }) | ||
, function(){ fsm.free(blkNum[2], props.minSpanNum()) }) | ||
it("fsm is equal to original NaiveFSM object", function(){ | ||
@@ -81,9 +81,9 @@ fsm.equal(ofsm) | ||
describe("fsm.alloc x3 props.minSpanNum, then fsm.free [0,2,1]", function(){ | ||
describe("fsm.alloc x3 props.minSpanNum(), then fsm.free [0,2,1]", function(){ | ||
var blkNum = [] | ||
describe("fsm.alloc x3 props.minSpanNum", function(){ | ||
describe("fsm.alloc x3 props.minSpanNum()", function(){ | ||
it(".alloc() blkNum[0..2]", function(){ | ||
for (var i=0; i<3; i++) { | ||
blkNum[i] = fsm.alloc(props.minSpanNum) | ||
blkNum[i] = fsm.alloc(props.minSpanNum()) | ||
expect(blkNum[i]).to.be.a('number') | ||
@@ -114,3 +114,3 @@ } | ||
//first span; only one span freed; one total | ||
fsm.free(blkNum[0], props.minSpanNum) | ||
fsm.free(blkNum[0], props.minSpanNum()) | ||
//first free span is separated from any bigger one by other two | ||
@@ -124,3 +124,3 @@ expect(fsm.spans[0].length).to.equal(1) | ||
//third span; only one span freed; two total | ||
fsm.free(blkNum[2], props.minSpanNum) | ||
fsm.free(blkNum[2], props.minSpanNum()) | ||
//first free span is separated from any bigger one by other two | ||
@@ -134,3 +134,3 @@ expect(fsm.spans[0].length).to.equal(1) | ||
//second span; should merge spans with first and thirteenth | ||
fsm.free(blkNum[1], props.minSpanNum) | ||
fsm.free(blkNum[1], props.minSpanNum()) | ||
expect(fsm.spans[15].length).to.equal(2047) | ||
@@ -145,9 +145,9 @@ }) | ||
describe("fsm.alloc x3 props.maxSpanNum, then fsm.free [0,1,2]", function(){ | ||
describe("fsm.alloc x3 props.maxSpanNum(), then fsm.free [0,1,2]", function(){ | ||
var blkNum = [] | ||
describe("fsm.alloc x3 props.maxSpanNum", function(){ | ||
describe("fsm.alloc x3 props.maxSpanNum()", function(){ | ||
it(".alloc() blkNum[0..2]", function(){ | ||
for (var i=0; i<3; i++) { | ||
blkNum[i] = fsm.alloc(props.maxSpanNum) | ||
blkNum[i] = fsm.alloc(props.maxSpanNum()) | ||
@@ -167,7 +167,7 @@ expect(blkNum[i]).to.be.a('number') | ||
it("fsm.free blkNum[0]" | ||
, function(){ fsm.free(blkNum[0], props.maxSpanNum) }) | ||
, function(){ fsm.free(blkNum[0], props.maxSpanNum()) }) | ||
it("fsm.free blkNum[1]" | ||
, function(){ fsm.free(blkNum[1], props.maxSpanNum) }) | ||
, function(){ fsm.free(blkNum[1], props.maxSpanNum()) }) | ||
it("fsm.free blkNum[2]" | ||
, function(){ fsm.free(blkNum[2], props.maxSpanNum) }) | ||
, function(){ fsm.free(blkNum[2], props.maxSpanNum()) }) | ||
it("fsm is equal to original NaiveFSM object", function(){ | ||
@@ -180,9 +180,9 @@ fsm.equal(ofsm) | ||
describe("fsm.alloc x3 props.maxSpanNum, then fsm.free [0,2,1]", function(){ | ||
describe("fsm.alloc x3 props.maxSpanNum(), then fsm.free [0,2,1]", function(){ | ||
var blkNum = [] | ||
describe("fsm.alloc x3 props.maxSpanNum", function(){ | ||
describe("fsm.alloc x3 props.maxSpanNum()", function(){ | ||
it(".alloc() blkNum[0..2]", function(){ | ||
for (var i=0; i<3; i++) { | ||
blkNum[i] = fsm.alloc(props.maxSpanNum) | ||
blkNum[i] = fsm.alloc(props.maxSpanNum()) | ||
@@ -196,7 +196,7 @@ expect(blkNum[i]).to.be.a('number') | ||
it("fsm.free blkNum[0]" | ||
, function(){ fsm.free(blkNum[0], props.minSpanNum) }) | ||
, function(){ fsm.free(blkNum[0], props.minSpanNum()) }) | ||
it("fsm.free blkNum[2]" | ||
, function(){ fsm.free(blkNum[2], props.minSpanNum) }) | ||
, function(){ fsm.free(blkNum[2], props.minSpanNum()) }) | ||
it("fsm.free blkNum[1]" | ||
, function(){ fsm.free(blkNum[1], props.minSpanNum) }) | ||
, function(){ fsm.free(blkNum[1], props.minSpanNum()) }) | ||
it("fsm is equal to original NaiveFSM object", function(){ | ||
@@ -203,0 +203,0 @@ fsm.equal(ofsm) |
@@ -21,3 +21,3 @@ /* global describe it */ | ||
var seg, oseg, segNum, hdl | ||
, buf = new Buffer(props.blockSize) | ||
, buf = new Buffer(props.fsmSize()) | ||
@@ -24,0 +24,0 @@ buf.fill(0xff) |
@@ -19,4 +19,4 @@ /* global describe it */ | ||
, props = Props.defaultProps | ||
, NUM_SPANNUM = props.numSpanNums | ||
, NUM_BLOCKNUM = props.numBlkNums | ||
, NUM_SPANNUM = props.numSpanNums() | ||
, NUM_BLOCKNUM = props.numBlkNums() | ||
@@ -23,0 +23,0 @@ var filename ='test.bf' |
@@ -139,8 +139,8 @@ /* global describe it */ | ||
it("Write bf.props.numBlkNums lorem1k buffers", function(done){ | ||
it("Write bf.props.numBlkNums() lorem1k buffers", function(done){ | ||
this.timeout(20*1000) | ||
lastIdx = 0 | ||
nextIdx = lastIdx + (bf.props.numBlkNums-1) | ||
nextIdx = lastIdx + (bf.props.numBlkNums()-1) | ||
//utils.err("numBlkNums-1 = %j", bf.props.numBlkNums-1) | ||
//utils.err("numBlkNums-1 = %j", bf.props.numBlkNums()-1) | ||
@@ -218,8 +218,8 @@ if (USE_ASYNC) { | ||
it("Write bf.props.numBlkNums/64 lorem1k buffers", function(done){ | ||
it("Write bf.props.numBlkNums()/64 lorem1k buffers", function(done){ | ||
this.timeout(2*1000) | ||
lastIdx = nextIdx | ||
nextIdx += ceil(bf.props.numBlkNums/64) - 1 | ||
nextIdx += ceil(bf.props.numBlkNums()/64) - 1 | ||
//utils.err("ceil(numBlkNums/64-1 = %j)", ceil(bf.props.numBlkNums/64)-1) | ||
//utils.err("ceil(numBlkNums/64-1 = %j)", ceil(bf.props.numBlkNums()/64)-1) | ||
@@ -226,0 +226,0 @@ if (USE_ASYNC) { |
170994
2696
186
4
18