コード例 #1
0
        //private const int ObjectBlockCountThreshold = 64;
        /// <summary>
        /// If in AutoFlush mode and data Value is not saved in Key segment,
        /// this method will Add/Update Big Data Value to disk and at end of the process,
        /// set the Value to null to conserve memory.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private bool SetBigDataValue(BTreeItemOnDisk item)
        {
            if (!IsDataInKeySegment)
            {
                // load meta data so Blocks layout in-memory can get recreated...
                long da = GetId(item.Value.DiskBuffer);
                if (da >= 0)
                {
                    if (!item.Value.DiskBuffer.IsFolded)
                    {
                        if (item.Value.DiskBuffer.IsFoldedInfoOnDisk)
                        {
                            // read the block chain info so these blocks will not be replaced during update!
                            var metaBlocks = DataBlockDriver.ReadBlockInfoFromDisk(this, da);
                            // assign read block chain info to a DataBlock simulating a "Folded" scenario.
                            item.Value.diskBuffer.foldedDataAddresses  = metaBlocks.ToArray();
                            item.Value.diskBuffer.contiguousBlockCount = metaBlocks[0].BlockCount;
                        }
                    }
                    // delete the blocks on disk if they are big and data being set is null
                    if (item.Value.Data == null &&
                        item.Value.DiskBuffer.IsFolded &&
                        item.Value.DiskBuffer.CountMembers() >= 1024)
                    {
                        DataSet.DataBlockDriver.Remove(DataSet, item.Value.DiskBuffer);
                        item.Value.DiskBuffer = CreateBlock();
                    }
                }

                // save big data to disk
                if (item.Value.diskBuffer != null)
                {
                    item.Value.diskBuffer.Unfold(this);
                }
                Sop.DataBlock b = WriteToBlock(item.Value);
                DataSet.DataBlockDriver.SetDiskBlock(DataSet, b, false, false);
                var cnt = b.ProcessHeadSets();

                // store blocks to the pool if block count < 500, otherwise direct write to disk!
                if (cnt < File.Profile.BigDataBlockCount)
                {
                    AddToBlocks(b, Blocks);
                    item.ValueLoaded   = true;
                    item.Value.IsDirty = false;
                    item.IsDirty       = false;
                    item.Value.diskBuffer.Fold();
                }
                else
                {
                    if (cnt <= 500)
                    {
                        AddToBlocks(b, Blocks);
                    }
                    else
                    {
                        // direct write to disk
                        var blocks = new Collections.Generic.SortedDictionary <long, Sop.DataBlock>();
                        AddToBlocks(b, blocks);
                        WriteBlocksToDisk(DataSet, blocks, false);
                    }
                    item.IsDirty       = false;
                    item.Value.IsDirty = false;
                    item.ValueLoaded   = false;
                    item.Value.diskBuffer.Fold();
                    // nullify big data to conserve memory
                    item.Value.Data = null;
                }
                return(true);
            }
            return(false);
        }