Provides an indexed object which maps to buffers in an underlying file object
Exemple #1
0
        public static BufferFile SetupFromExistingStream(Stream fromfile, long startSeek)
        {
            var result = new BufferFile(fromfile, 100, startSeek);             // dummy buffer size for now

            result.ReadHeader();
            return(result);
        }
Exemple #2
0
        public static BufferFile InitializeBufferFileInStream(Stream fromfile, int buffersize, long startSeek)
        {
            var result = new BufferFile(fromfile, buffersize, startSeek);

            result.SetHeader();
            return(result);
        }
Exemple #3
0
        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);
            }
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        public static BufferFile InitializeBufferFileInStream(System.IO.Stream fromfile, int buffersize, long StartSeek)
        {
            BufferFile result = new BufferFile(fromfile, buffersize, StartSeek);

            result.setHeader();
            return(result);
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        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);
        }
Exemple #9
0
 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);
 }
Exemple #10
0
        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);
        }
Exemple #11
0
        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);
        }
Exemple #12
0
 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);
 }
Exemple #13
0
        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);
        }
Exemple #15
0
 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);
     }
 }
Exemple #16
0
		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;
		}
Exemple #17
0
 public static BufferFile InitializeBufferFileInStream(Stream fromfile, int buffersize, long startSeek)
 {
     var result = new BufferFile(fromfile, buffersize, startSeek);
     result.SetHeader();
     return result;
 }
Exemple #18
0
		public static BufferFile InitializeBufferFileInStream(System.IO.Stream fromfile, int buffersize, long StartSeek) 
		{
			BufferFile result = new BufferFile(fromfile, buffersize, StartSeek);
			result.setHeader();
			return result;
		}
Exemple #19
0
 public static BufferFile SetupFromExistingStream(Stream fromfile, long startSeek)
 {
     var result = new BufferFile(fromfile, 100, startSeek); // dummy buffer size for now
     result.ReadHeader();
     return result;
 }