Exemple #1
0
        /// <summary>
        /// Construct a tree from given storage, using the specified comparer of key
        /// </summary>
        /// <param name="keySerializer">Tool to serialize node keys.</param>
        /// <param name="valueSerializer">Tool to serialize node values<param>
        /// <param name="recordStorage">Underlying tool for storage.</param>
        /// <param name="keyComparer">Key comparer.</param>
        public TreeDiskNodeManager(ISerializer <K> keySerializer
                                   , ISerializer <V> valueSerializer
                                   , IRecordStorage recordStorage
                                   , IComparer <K> keyComparer)
        {
            if (recordStorage == null)
            {
                throw new ArgumentNullException("nodeStorge");
            }

            this.recordStorage = recordStorage;
            this.serializer    = new TreeDiskNodeSerializer <K, V> (this, keySerializer, valueSerializer);
            this.KeyComparer   = keyComparer;
            this.EntryComparer = Comparer <Tuple <K, V> > .Create((a, b) => {
                return(KeyComparer.Compare(a.Item1, b.Item1));
            });

            // The first record of nodeStorage stores id of root node,
            // if this record do not exist at the time this index instanitate,
            // then attempt to create it
            var firstBlockData = recordStorage.Find(1u);

            if (firstBlockData != null)
            {
                this.rootNode = Find(BufferHelper.ReadBufferUInt32(firstBlockData, 0));
            }
            else
            {
                this.rootNode = CreateFirstRoot();
            }
        }
Exemple #2
0
        public TreeNode <K, V> Find(uint id)
        {
            // Check if the node is being held in memory,
            // if it does then return it
            if (nodeWeakRefs.ContainsKey(id))
            {
                TreeNode <K, V> node;
                if (nodeWeakRefs[id].TryGetTarget(out node))
                {
                    return(node);
                }
                else
                {
                    // node deallocated, remove weak reference
                    nodeWeakRefs.Remove(id);
                }
            }

            // Not is not in memory, go get it
            var data = recordStorage.Find(id);

            if (data == null)
            {
                return(null);
            }
            var dNode = this.serializer.Deserialize(id, data);

            // Always keep reference to node we created
            OnNodeInitialized(dNode);
            return(dNode);
        }
        /// <summary>
        /// Returns a node with matching id.
        /// </summary>
        public TreeNode <K, V> Find(uint id)
        {
            // Check if the node exists in memory
            if (weakNodes.ContainsKey(id))
            {
                // Try getting the reference
                TreeNode <K, V> node = null;

                // If reference exists, return it
                if (weakNodes[id].TryGetValue(out node))
                {
                    return(node);
                }

                // If doesn't exist, it must have been collected by GC.
                weakNodes.Remove(id);
            }

            // Get data from record
            var data = recordStorage.Find(id);

            if (data == null)
            {
                return(null);
            }

            // Deserialize the data to create node.
            var diskNode = serializer.Deserialize(id, data);

            // Keep track of new nodes
            OnNodeInitialized(diskNode);
            // Return it
            return(diskNode);
        }
        public DiskTreeNodeManager(ISerializer <K> keySerializer, ISerializer <V> valueSerializer,
                                   IRecordStorage recordStorage, IComparer <K> keyComparer, DiskNodeOptions options = null)
        {
            if (recordStorage == null)
            {
                throw new ArgumentNullException("recordStorage");
            }
            if (options == null)
            {
                options = new DiskNodeOptions();
            }

            this.recordStorage = recordStorage;
            this.dirtyNodes    = new Dictionary <uint, TreeNode <K, V> >();
            this.weakNodes     = new Dictionary <uint, WeakReference <TreeNode <K, V> > >();
            this.strongNodes   = new Queue <TreeNode <K, V> >();
            this.serializer    = new DiskTreeNodeSerializer <K, V>(this, keySerializer, valueSerializer);
            this.keyComparer   = keyComparer;
            this.entryComparer = new TreeEntryComparer <K, V>(keyComparer);

            this.weakNodeCleanThreshold = options.WeakNodeCleanInterval;
            this.maxStrongNodes         = options.MaxStrongNode;
            this.minEntriesPerNode      = options.MinEntriesPerNode;

            this.deleteIds      = new List <uint>(weakNodeCleanThreshold / 2);
            this.cleanupCounter = 0;

            // Find or create the root node.
            var firstData = recordStorage.Find(1U);

            if (firstData != null)
            {
                this.rootNode = Find(BufferHelper.ReadUInt32(firstData, 0));
            }
            else
            {
                this.rootNode = CreateFirstRoot();
            }
        }