src/IndexEntry.js
/**
* This is the interface that an Entry class needs to implement.
* @interface
*/
class EntryInterface {
/**
* @abstract
* @returns {number} The byte size of this Entry.
*/
static get size() {}
/**
* Read a new Entry from a Buffer object at the given offset.
*
* @abstract
* @param {Buffer} buffer The buffer object to read the index data from.
* @param {number} [offset] The buffer offset to start reading from. Default 0.
* @returns {EntryInterface} A new entry matching the values from the Buffer.
*/
static fromBuffer(buffer, offset = 0) {}
/**
* Write this Entry into a Buffer object at the given offset.
*
* @abstract
* @param {Buffer} buffer The buffer object to write the index entry data to.
* @param {number} offset The offset to start writing into the buffer.
* @returns {number} The size of the data written.
*/
toBuffer(buffer, offset) {}
}
/**
* Assert that the given class is a valid EntryInterface class.
*
* @param {typeof EntryInterface} EntryClass The constructor for the class
* @throws {Error} if the given class does not implement the EntryInterface methods or has non-positive size
*/
function assertValidEntryClass(EntryClass) {
if (typeof EntryClass !== 'function'
|| typeof EntryClass.size === 'undefined'
|| typeof EntryClass.fromBuffer !== 'function'
|| typeof EntryClass.prototype.toBuffer !== 'function') {
throw new Error('Invalid index entry class. Must implement EntryInterface methods.');
}
if (EntryClass.size < 1) {
throw new Error('Entry class size must be positive.');
}
}
/**
* Default Entry item contains information about the sequence number, the file position, the document size and the partition number.
* @extends Array<number>
* @implements EntryInterface
*/
class Entry extends Array {
/**
* @param {number} number The sequence number of the index entry.
* @param {number} position The file position where the indexed document is stored.
* @param {number} [size] The size of the stored document (for verification). Default 0.
* @param {number} [partition] The partition where the indexed document is stored. Default 0.
*/
constructor(number, position, size = 0, partition = 0) {
super(4);
this[0] = number;
this[1] = position;
this[2] = size;
this[3] = partition;
}
/**
* @returns {number} The byte size of this Entry. Always 16.
*/
static get size() {
return 4 * 4;
}
/**
* Read a new Entry from a Buffer object at the given offset.
*
* @param {Buffer} buffer The buffer object to read the index data from. Will read four 32-Bit LE unsigned integers.
* @param {number} [offset] The buffer offset to start reading from. Default 0.
* @returns {Entry} A new entry matching the values from the Buffer.
*/
static fromBuffer(buffer, offset = 0) {
const number = buffer.readUInt32LE(offset);
const position = buffer.readUInt32LE(offset + 4);
const size = buffer.readUInt32LE(offset + 8);
const partition = buffer.readUInt32LE(offset + 12);
return new this(number, position, size, partition);
}
/**
* Write this Entry into a Buffer object at the given offset.
*
* @param {Buffer} buffer The buffer object to write the index entry data to. Will write four 32-Bit LE unsigned integers.
* @param {number} offset The offset to start writing into the buffer.
* @returns {number} The size of the data written. Will always be 16.
*/
toBuffer(buffer, offset) {
buffer.writeUInt32LE(this[0], offset);
buffer.writeUInt32LE(this[1], offset + 4);
buffer.writeUInt32LE(this[2], offset + 8);
buffer.writeUInt32LE(this[3], offset + 12);
return Entry.size;
}
/**
* @returns {number}
*/
get number() {
return this[0];
}
/**
* @returns {number}
*/
get position() {
return this[1];
}
/**
* @returns {number}
*/
get size() {
return this[2];
}
/**
* @returns {number}
*/
get partition() {
return this[3];
}
}
module.exports = Entry;
module.exports.EntryInterface = EntryInterface;
module.exports.assertValidEntryClass = assertValidEntryClass;