/// <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(); } }
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(); } }