Exemplo n.º 1
0
        private long internalWriteData(StorageItem <T> meta, byte[] data, bool raw)
        {
            lock (_readlock)
            {
                _dirty = true;
                // seek end of file
                long offset = _lastWriteOffset;
                if (_viewmode == false && Global.SplitStorageFilesMegaBytes > 0)
                {
                    // current file size > _splitMegaBytes --> new file
                    if (offset > (long)Global.SplitStorageFilesMegaBytes * 1024 * 1024)
                    {
                        CreateNewStorageFile();
                    }
                }

                if (raw == false)
                {
                    if (data != null)
                    {
                        meta.dataLength = data.Length;
                    }
                    byte[] metabytes = fastBinaryJSON.BJSON.ToBJSON(meta, new fastBinaryJSON.BJSONParameters {
                        UseExtensions = false, UseTypedArrays = false
                    });

                    // write header info
                    _datawrite.Write(new byte[] { 1 }, 0, 1); // FEATURE : add json here, write bson for now
                    _datawrite.Write(Helper.GetBytes(metabytes.Length, false), 0, 4);
                    _datawrite.Write(metabytes, 0, metabytes.Length);
                    // update pointer
                    _lastWriteOffset += metabytes.Length + 5;
                }
                else
                {
                    // write header info
                    _datawrite.Write(new byte[] { 0 }, 0, 1); // write raw
                    _datawrite.Write(Helper.GetBytes(data.Length, false), 0, 4);
                    // update pointer
                    _lastWriteOffset += 5;
                }

                if (data != null)
                {
                    // write data block
                    _datawrite.Write(data, 0, data.Length);
                    _lastWriteOffset += data.Length;
                }
                // return starting offset -> recno
                long recno = _lastRecordNum++;
                if (_recfilewrite != null)
                {
                    _recfilewrite.Write(Helper.GetBytes(offset, false), 0, 8);
                }
                if (Global.FlushStorageFileImmediately)
                {
                    _datawrite.Flush();
                    if (_recfilewrite != null)
                    {
                        _recfilewrite.Flush();
                    }
                }
                return(recno);
            }
        }
Exemplo n.º 2
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
                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);
            }
        }
Exemplo n.º 3
0
 public byte[] GetBytes(DateTime obj)
 {
     return(Helper.GetBytes(obj.Ticks, false));
 }
Exemplo n.º 4
0
 public byte[] GetBytes(long obj)
 {
     return(Helper.GetBytes(obj, false));
 }
Exemplo n.º 5
0
 public byte[] GetBytes(string obj)
 {
     return(Helper.GetBytes(obj));
 }
Exemplo n.º 6
0
 public byte[] GetBytes(short obj)
 {
     return(Helper.GetBytes(obj, false));
 }
Exemplo n.º 7
0
        public void Optimize()
        {
            lock (_oplock)
            {
                lock (_readlock)
                {
                    lock (_writelock)
                    {
                        String _filePath = Path.GetDirectoryName(_filename);

                        String _bmpTempName = Path.ChangeExtension(Path.Combine(_filePath, Path.GetFileNameWithoutExtension(_filename) + "$"), _bmpExt);
                        String _recTempName = Path.ChangeExtension(Path.Combine(_filePath, Path.GetFileNameWithoutExtension(_filename) + "$"), _recExt);
                        String _bmpName     = Path.ChangeExtension(_filename, _bmpExt);
                        String _recName     = Path.ChangeExtension(_filename, _recExt);

                        _stopOperations = true;

                        while (_workingCount > 0)
                        {
                            Thread.SpinWait(1);
                        }

                        Flush();

                        if (File.Exists(_bmpTempName))
                        {
                            File.Delete(_bmpTempName);
                        }

                        if (File.Exists(_recTempName))
                        {
                            File.Delete(_recTempName);
                        }

                        Stream _newrec = new FileStream(_bmpTempName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                        Stream _newbmp = new FileStream(_recTempName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);

                        long newoffset = 0;
                        int  c         = (int)(_recordFileRead.Length / 8);
                        for (int i = 0; i < c; i++)
                        {
                            long offset = ReadRecordOffset(i);

                            byte[] b = ReadBMPDataForOptimize(offset);
                            if (b == null)
                            {
                                _stopOperations = false;
                                throw new Exception("bitmap index file is corrupted");
                            }

                            _newrec.Write(Helper.GetBytes(newoffset, false), 0, 8);
                            newoffset += b.Length;
                            _newbmp.Write(b, 0, b.Length);
                        }
                        _newbmp.Flush();
                        _newbmp.Close();
                        _newrec.Flush();
                        _newrec.Close();

                        InternalShutdown();

                        File.Delete(_bmpName);
                        File.Delete(_recName);
                        File.Move(_bmpTempName, _bmpName);
                        File.Move(_recTempName, _recName);

                        Initialize();
                        _stopOperations = false;
                    }
                }
            }
        }