private void Commit(CancellationToken cancellationToken, Locator locator = default(Locator), bool hasLocator = false, IData fromKey = null, IData toKey = null) { if (disposed) { throw new ObjectDisposedException("WTree"); } Params param; if (!hasLocator) { param = new Params(WalkMethod.CascadeButOnlyLoaded, WalkAction.Store, null, false); } else { if (fromKey == null) { param = new Params(WalkMethod.CascadeButOnlyLoaded, WalkAction.Store, null, false, locator); } else { if (toKey == null) { param = new Params(WalkMethod.CascadeButOnlyLoaded, WalkAction.Store, null, false, locator, fromKey); } else { param = new Params(WalkMethod.CascadeButOnlyLoaded, WalkAction.Store, null, false, locator, fromKey, toKey); } } } lock (RootBranch) { if (!isRootCacheLoaded) { LoadRootCache(); } Token token = new Token(CacheSemaphore, cancellationToken); RootBranch.Fall(Depth + 1, token, param); token.CountdownEvent.Signal(); token.CountdownEvent.Wait(); //write settings using (MemoryStream ms = new MemoryStream()) { Settings.Serialize(this, ms); heap.Write(HANDLE_SETTINGS, ms.GetBuffer(), 0, (int)ms.Length); } //write scheme using (MemoryStream ms = new MemoryStream()) { scheme.Serialize(new BinaryWriter(ms)); heap.Write(HANDLE_SCHEME, ms.GetBuffer(), 0, (int)ms.Length); } //write root cache using (MemoryStream ms = new MemoryStream()) { RootBranch.Cache.Store(this, new BinaryWriter(ms)); heap.Write(HANDLE_ROOT, ms.GetBuffer(), 0, (int)ms.Length); } heap.Commit(); } }
private void SerializeLocator(BinaryWriter writer, Locator locator) { writer.Write(locator.ID); }
/// <summary> /// The hook. /// </summary> public IOrderedSet <IData, IData> FindData(Locator originalLocator, Locator locator, IData key, Direction direction, out FullKey nearFullKey, out bool hasNearFullKey, ref FullKey lastVisitedFullKey) { if (disposed) { throw new ObjectDisposedException("WTree"); } nearFullKey = default(FullKey); hasNearFullKey = false; var branch = RootBranch; Monitor.Enter(branch); if (!isRootCacheLoaded) { LoadRootCache(); } Params param; if (key != null) { param = new Params(WalkMethod.Cascade, WalkAction.None, null, true, locator, key); } else { switch (direction) { case Direction.Forward: param = new Params(WalkMethod.CascadeFirst, WalkAction.None, null, true, locator); break; case Direction.Backward: param = new Params(WalkMethod.CascadeLast, WalkAction.None, null, true, locator); break; default: throw new NotSupportedException(direction.ToString()); } } branch.Fall(Depth + 1, new Token(CacheSemaphore, CancellationToken.None), param); branch.WaitFall(); switch (direction) { case Direction.Forward: { while (branch.NodeType == NodeType.Internal) { KeyValuePair <FullKey, Branch> newBranch = ((InternalNode)branch.Node).FindBranch(locator, key, direction, ref nearFullKey, ref hasNearFullKey); Monitor.Enter(newBranch.Value); newBranch.Value.WaitFall(); Debug.Assert(!newBranch.Value.Cache.Contains(originalLocator)); Monitor.Exit(branch); branch = newBranch.Value; } } break; case Direction.Backward: { int depth = Depth; KeyValuePair <FullKey, Branch> newBranch = default(KeyValuePair <FullKey, Branch>); while (branch.NodeType == NodeType.Internal) { InternalNode node = (InternalNode)branch.Node; newBranch = node.Branches[node.Branches.Count - 1]; int cmp = newBranch.Key.Locator.CompareTo(lastVisitedFullKey.Locator); if (cmp == 0) { if (lastVisitedFullKey.Key == null) { cmp = -1; } else { cmp = newBranch.Key.Locator.KeyComparer.Compare(newBranch.Key.Key, lastVisitedFullKey.Key); } } //else //{ // Debug.WriteLine(""); //} //newBranch.Key.CompareTo(lastVisitedFullKey) >= 0 if (cmp >= 0) { newBranch = node.FindBranch(locator, key, direction, ref nearFullKey, ref hasNearFullKey); } else { if (node.Branches.Count >= 2) { hasNearFullKey = true; nearFullKey = node.Branches[node.Branches.Count - 2].Key; } } Monitor.Enter(newBranch.Value); depth--; newBranch.Value.WaitFall(); if (newBranch.Value.Cache.Contains(originalLocator)) { newBranch.Value.Fall(depth + 1, new Token(CacheSemaphore, CancellationToken.None), new Params(WalkMethod.Current, WalkAction.None, null, true, originalLocator)); newBranch.Value.WaitFall(); } Debug.Assert(!newBranch.Value.Cache.Contains(originalLocator)); Monitor.Exit(branch); branch = newBranch.Value; } //if (lastVisitedFullKey.Locator.Equals(newBranch.Key.Locator) && // (lastVisitedFullKey.Key != null && lastVisitedFullKey.Locator.KeyEqualityComparer.Equals(lastVisitedFullKey.Key, newBranch.Key.Key))) //{ // Monitor.Exit(branch); // return null; //} lastVisitedFullKey = newBranch.Key; } break; default: throw new NotSupportedException(direction.ToString()); } IOrderedSet <IData, IData> data = ((LeafNode)branch.Node).FindData(originalLocator, direction, ref nearFullKey, ref hasNearFullKey); Monitor.Exit(branch); return(data); }