Exemple #1
0
        internal void SavePage(Page <T> node)
        {
            lock (_fileLock)
            {
                int pnum = node.DiskPageNumber;
                if (pnum > _LastPageNumber)
                {
                    throw new Exception("should not be here: page out of bounds");
                }

                SeekPage(pnum);
                byte[] page        = new byte[_PageLength];
                byte[] blockheader = CreateBlockHeader(0, (ushort)node.tree.Count, node.RightPageNumber);
                Buffer.BlockCopy(blockheader, 0, page, 0, blockheader.Length);

                int    index = blockheader.Length;
                int    i     = 0;
                byte[] b     = null;
                T[]    keys  = node.tree.Keys();
                Array.Sort(keys); // sort keys on save for read performance
                // node children
                foreach (var kp in keys)
                {
                    var val = node.tree[kp];
                    int idx = index + _rowSize * i++;
                    // key bytes
                    byte[] kk   = _T.GetBytes(kp);
                    byte   size = (byte)kk.Length;
                    if (size > _maxKeySize)
                    {
                        size = _maxKeySize;
                    }
                    // key size = 1 byte
                    page[idx] = size;
                    Buffer.BlockCopy(kk, 0, page, idx + 1, page[idx]);
                    // offset = 4 bytes
                    b = Helper.GetBytes(val.RecordNumber, false);
                    Buffer.BlockCopy(b, 0, page, idx + 1 + _maxKeySize, b.Length);
                    // duplicatepage = 4 bytes
                    b = Helper.GetBytes(val.DuplicateBitmapNumber, false);
                    Buffer.BlockCopy(b, 0, page, idx + 1 + _maxKeySize + 4, b.Length);
                }
                _file.Write(page, 0, page.Length);
            }
        }
Exemple #2
0
        public bool RemoveKey(T key)
        {
            // remove and store key in storage file
            byte[]       bkey = _T.GetBytes(key);
            MemoryStream ms   = new MemoryStream();

            ms.Write(Helper.GetBytes(bkey.Length, false), 0, 4);
            ms.Write(bkey, 0, bkey.Length);
            return(Delete(key, ms.ToArray()));
        }
Exemple #3
0
        public int WriteData(T key, byte[] data, bool deleted)
        {
            byte[] k  = _T.GetBytes(key);
            int    kl = k.Length;

            // seek end of file
            long offset = _lastWriteOffset;

            byte[] hdr = CreateRowHeader(kl, (data == null?0:data.Length));
            if (deleted)
            {
                hdr[(int)HDR_POS.Flags] = (byte)1;
            }
            // write header info
            _writefile.Write(hdr, 0, hdr.Length);
            // write key
            _writefile.Write(k, 0, kl);
            if (data != null)
            {
                // write data block
                _writefile.Write(data, 0, data.Length);
                if (Global.FlushStorageFileImmetiatley)
                {
                    _writefile.Flush();
                }
                _lastWriteOffset += data.Length;
            }
            // update pointer
            _lastWriteOffset += hdr.Length;
            _lastWriteOffset += kl;
            // return starting offset -> recno
            int recno = _lastRecordNum++;

            _recordfile.Write(Helper.GetBytes(offset, false), 0, 8);
            if (Global.FlushStorageFileImmetiatley)
            {
                _recordfile.Flush();
            }
            _flushNeeded = true;
            return(recno);
        }
        internal void SavePage(Page <T> node)
        {
            lock (_fileLock)
            {
                int pnum = node.DiskPageNumber;
                if (pnum > _LastPageNumber)
                {
                    throw new Exception("should not be here: page out of bounds");
                }

                SeekPage(pnum);
                byte[] page        = new byte[_PageLength];
                byte[] blockheader = CreateBlockHeader(0, (ushort)node.tree.Count(), node.RightPageNumber);
                Buffer.BlockCopy(blockheader, 0, page, 0, blockheader.Length);

                int    index = blockheader.Length;
                int    i     = 0;
                byte[] b     = null;
                T[]    keys  = node.tree.Keys();
                Array.Sort(keys); // sort keys on save for read performance
                int blocknum = 0;
                if (_externalStrings)
                {
                    // free old blocks
                    if (node.allocblocks != null)
                    {
                        _strings.FreeBlocks(node.allocblocks);
                    }
                    blocknum = _strings.SaveData(node.DiskPageNumber.ToString(), BJSON.ToBJSON(keys,
                                                                                               new BJSONParameters {
                        UseUnicodeStrings = false, UseTypedArrays = false
                    }));
                }
                // node children
                foreach (var kp in keys)
                {
                    var val = node.tree[kp];
                    int idx = index + _rowSize * i;
                    // key bytes
                    byte[] kk;
                    byte   size;
                    if (_externalStrings == false)
                    {
                        kk   = _T.GetBytes(kp);
                        size = (byte)kk.Length;
                        if (size > _maxKeySize)
                        {
                            size = _maxKeySize;
                        }
                    }
                    else
                    {
                        kk = new byte[4];
                        Buffer.BlockCopy(Helper.GetBytes(blocknum, false), 0, kk, 0, 4);
                        size = 4;
                    }
                    // key size = 1 byte
                    page[idx] = size;
                    Buffer.BlockCopy(kk, 0, page, idx + 1, page[idx]);
                    // offset = 4 bytes
                    b = Helper.GetBytes(val.RecordNumber, false);
                    Buffer.BlockCopy(b, 0, page, idx + 1 + _maxKeySize, b.Length);
                    // duplicatepage = 4 bytes
                    b = Helper.GetBytes(val.DuplicateBitmapNumber, false);
                    Buffer.BlockCopy(b, 0, page, idx + 1 + _maxKeySize + 4, b.Length);
                    i++;
                }
                _file.Write(page, 0, page.Length);
            }
        }