public static BufferFile SetupFromExistingStream(Stream fromfile, long startSeek) { var result = new BufferFile(fromfile, 100, startSeek); // dummy buffer size for now result.ReadHeader(); return(result); }
public static BufferFile InitializeBufferFileInStream(Stream fromfile, int buffersize, long startSeek) { var result = new BufferFile(fromfile, buffersize, startSeek); result.SetHeader(); return(result); }
void readHeader() { byte[] header = new byte[this.headersize]; this.fromfile.Seek(this.seekStart, System.IO.SeekOrigin.Begin); this.fromfile.Read(header, 0, this.headersize); int index = 0; // check prefix foreach (byte b in HEADERPREFIX) { if (header[index] != b) { throw new LinkedFileException("invalid header prefix"); } index++; } // skip version (for now) index++; // read buffersize this.buffersize = BufferFile.Retrieve(header, index); index += BufferFile.INTSTORAGE; this.FreeListHead = BufferFile.RetrieveLong(header, index); this.sanityCheck(); this.headerDirty = false; }
public void Load(byte[] serialization) { int index = 0; int byteCount = serialization.Length; if (this.values.Count != 0 || this.keys.Count != 0) { throw new BplusTreeException("load into nonempty xBucket not permitted"); } while (index < byteCount) { // get key prefix and key int keylength = BufferFile.Retrieve(serialization, index); index += BufferFile.INTSTORAGE; byte[] keybytes = new byte[keylength]; Array.Copy(serialization, index, keybytes, 0, keylength); string keystring = BplusTree.BytesToString(keybytes); index += keylength; // get value prefix and value int valuelength = BufferFile.Retrieve(serialization, index); index += BufferFile.INTSTORAGE; byte[] valuebytes = new byte[valuelength]; Array.Copy(serialization, index, valuebytes, 0, valuelength); // record new key and value this.keys.Add(keystring); this.values.Add(valuebytes); index += valuelength; } if (index != byteCount) { throw new BplusTreeException("bad byte count in serialization " + byteCount); } }
public static BufferFile SetupFromExistingStream(System.IO.Stream fromfile, long StartSeek) { BufferFile result = new BufferFile(fromfile, 100, StartSeek); // dummy buffer size for now result.readHeader(); return(result); }
public static BufferFile InitializeBufferFileInStream(System.IO.Stream fromfile, int buffersize, long StartSeek) { BufferFile result = new BufferFile(fromfile, buffersize, StartSeek); result.setHeader(); return(result); }
public static LinkedFile SetupFromExistingStream(System.IO.Stream fromfile, long StartSeek) { LinkedFile result = new LinkedFile(100, StartSeek); // dummy buffer size for now result.fromfile = fromfile; result.readHeader(); result.buffers = BufferFile.SetupFromExistingStream(fromfile, StartSeek + result.headersize); return(result); }
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); }
byte[] ParseBuffer(long bufferNumber, out byte type, out long nextBufferNumber) { byte[] thebuffer = new byte[this.buffersize]; byte[] fullbuffer = new byte[this.buffersize + BUFFEROVERHEAD]; this.buffers.getBuffer(bufferNumber, fullbuffer, 0, fullbuffer.Length); type = fullbuffer[0]; nextBufferNumber = BufferFile.RetrieveLong(fullbuffer, 1); Array.Copy(fullbuffer, BUFFEROVERHEAD, thebuffer, 0, this.buffersize); return(thebuffer); }
public static LinkedFile InitializeLinkedFileInStream(System.IO.Stream fromfile, int buffersize, long StartSeek) { LinkedFile result = new LinkedFile(buffersize, StartSeek); result.fromfile = fromfile; result.setHeader(); // buffersize should be increased by overhead... result.buffers = BufferFile.InitializeBufferFileInStream(fromfile, buffersize + BUFFEROVERHEAD, StartSeek + result.headersize); 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[] GetChunk(long HeadBufferNumber) { // get the head, interpret the length byte buffertype; long nextBufferNumber; byte[] buffer = this.ParseBuffer(HeadBufferNumber, out buffertype, out nextBufferNumber); int length = BufferFile.Retrieve(buffer, 0); if (length < 0) { throw new LinkedFileException("negative length block? must be garbage: " + length); } if (buffertype != HEAD) { throw new LinkedFileException("first buffer not marked HEAD"); } byte[] result = new byte[length]; // read in the data from the first buffer int firstLength = this.buffersize - BufferFile.INTSTORAGE; if (firstLength > length) { firstLength = length; } Array.Copy(buffer, BufferFile.INTSTORAGE, result, 0, firstLength); int stored = firstLength; while (stored < length) { // get the next buffer long thisBufferNumber = nextBufferNumber; buffer = this.ParseBuffer(thisBufferNumber, out buffertype, out nextBufferNumber); int nextLength = this.buffersize; if (length - stored < nextLength) { nextLength = length - stored; } Array.Copy(buffer, 0, result, stored, nextLength); stored += nextLength; } return(result); }
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); }
public void Recover(bool CorrectErrors) { Hashtable visited = new Hashtable(); if (this.root!=null) { // find all reachable nodes this.root.SanityCheck(visited); } // traverse the free list long freebuffernumber = this.freeHeadSeek; while (freebuffernumber!=NULLBUFFERNUMBER) { if (visited.ContainsKey(freebuffernumber) ) { throw new BplusTreeException("free buffer visited twice "+freebuffernumber); } visited[freebuffernumber] = FREE; freebuffernumber = this.parseFreeBuffer(freebuffernumber); } // find out what is missing Hashtable Missing = new Hashtable(); long maxbuffer = this.buffers.nextBufferNumber(); for (long i=0; i<maxbuffer; i++) { if (!visited.ContainsKey(i)) { Missing[i] = i; } } // remove from missing any free-on-commit blocks foreach (DictionaryEntry thing in this.FreeBuffersOnCommit) { long tobefreed = (long) thing.Key; Missing.Remove(tobefreed); } // add the missing values to the free list if (CorrectErrors) { if (Missing.Count>0) { System.Diagnostics.Debug.WriteLine("correcting "+Missing.Count+" unreachable buffers"); } ArrayList missingL = new ArrayList(); foreach (DictionaryEntry d in Missing) { missingL.Add(d.Key); } missingL.Sort(); missingL.Reverse(); foreach (object thing in missingL) { long buffernumber = (long) thing; this.deallocateBuffer(buffernumber); } //this.ResetBookkeeping(); } else if (Missing.Count>0) { string buffers = ""; foreach (DictionaryEntry thing in Missing) { buffers += " "+thing.Key; } throw new BplusTreeException("found "+Missing.Count+" unreachable buffers."+buffers); } }
public static BufferFile SetupFromExistingStream(System.IO.Stream fromfile, long StartSeek) { BufferFile result = new BufferFile(fromfile, 100, StartSeek); // dummy buffer size for now result.readHeader(); return result; }
public static BufferFile InitializeBufferFileInStream(Stream fromfile, int buffersize, long startSeek) { var result = new BufferFile(fromfile, buffersize, startSeek); result.SetHeader(); return result; }
public static BufferFile InitializeBufferFileInStream(System.IO.Stream fromfile, int buffersize, long StartSeek) { BufferFile result = new BufferFile(fromfile, buffersize, StartSeek); result.setHeader(); return result; }
public static BufferFile SetupFromExistingStream(Stream fromfile, long startSeek) { var result = new BufferFile(fromfile, 100, startSeek); // dummy buffer size for now result.ReadHeader(); return result; }