public long StoreNewChunk(byte[] fromArray, int startingAt, int length) { // get the first buffer as result value long currentBufferNumber = this.AllocateBuffer(); //System.Diagnostics.Debug.WriteLine(" allocating chunk starting at "+currentBufferNumber); long result = currentBufferNumber; if (length < 0 || startingAt < 0) { throw new LinkedFileException("cannot store negative length chunk (" + startingAt + "," + length + ")"); } int endingAt = startingAt + length; // special case: zero length chunk if (endingAt > fromArray.Length) { throw new LinkedFileException("array doesn't have this much data: " + endingAt); } int index = startingAt; // store header with length information byte[] buffer = new byte[this.buffersize]; BufferFile.Store(length, buffer, 0); int fromIndex = startingAt; int firstLength = this.buffersize - BufferFile.INTSTORAGE; int stored = 0; if (firstLength > length) { firstLength = length; } Array.Copy(fromArray, fromIndex, buffer, BufferFile.INTSTORAGE, firstLength); stored += firstLength; fromIndex += firstLength; byte currentBufferType = HEAD; // store any remaining buffers (no length info) while (stored < length) { // store current buffer and get next block number long nextBufferNumber = this.AllocateBuffer(); this.SetBuffer(currentBufferNumber, currentBufferType, buffer, 0, buffer.Length, nextBufferNumber); currentBufferNumber = nextBufferNumber; currentBufferType = BODY; int nextLength = this.buffersize; if (stored + nextLength > length) { nextLength = length - stored; } Array.Copy(fromArray, fromIndex, buffer, 0, nextLength); stored += nextLength; fromIndex += nextLength; } // store final buffer this.SetBuffer(currentBufferNumber, currentBufferType, buffer, 0, buffer.Length, NULLBUFFERPOINTER); return(result); }
public byte[] MakeHeader() { byte[] result = new byte[this.headersize]; HEADERPREFIX.CopyTo(result, 0); result[HEADERPREFIX.Length] = VERSION; int index = HEADERPREFIX.Length + 1; BufferFile.Store(this.buffersize, result, index); index += BufferFile.INTSTORAGE; BufferFile.Store(this.FreeListHead, result, index); return(result); }
void SetBuffer(long buffernumber, byte type, byte[] thebuffer, int start, int length, long nextBufferNumber) { //System.Diagnostics.Debug.WriteLine(" storing chunk type "+type+" at "+buffernumber); if (this.buffersize < length) { throw new LinkedFileException("buffer size too small " + this.buffersize + "<" + length); } byte[] fullbuffer = new byte[length + BUFFEROVERHEAD]; fullbuffer[0] = type; BufferFile.Store(nextBufferNumber, fullbuffer, 1); if (thebuffer != null) { Array.Copy(thebuffer, start, fullbuffer, BUFFEROVERHEAD, length); } this.buffers.SetBuffer(buffernumber, fullbuffer, 0, fullbuffer.Length); }
public byte[] Dump() { ArrayList allbytes = new ArrayList(); int byteCount = 0; for (int index = 0; index < this.keys.Count; index++) { string thisKey = (string)this.keys[index]; byte[] thisValue = (byte[])this.values[index]; byte[] keyprefix = new byte[BufferFile.INTSTORAGE]; byte[] keybytes = BplusTree.StringToBytes(thisKey); BufferFile.Store(keybytes.Length, keyprefix, 0); allbytes.Add(keyprefix); allbytes.Add(keybytes); byte[] valueprefix = new byte[BufferFile.INTSTORAGE]; BufferFile.Store(thisValue.Length, valueprefix, 0); allbytes.Add(valueprefix); allbytes.Add(thisValue); } foreach (object thing in allbytes) { byte[] thebytes = (byte[])thing; byteCount += thebytes.Length; } int outindex = 0; byte[] result = new byte[byteCount]; foreach (object thing in allbytes) { byte[] thebytes = (byte[])thing; int thelength = thebytes.Length; Array.Copy(thebytes, 0, result, outindex, thelength); outindex += thelength; } if (outindex != byteCount) { throw new BplusTreeException("error counting bytes in dump " + outindex + "!=" + byteCount); } return(result); }