public ITypedStream GetTypedStream(OpenMode mode, Type t) { lock (SyncRoot) { AssertNotDisposed(); if (mode != OpenMode.Read) { AssertCurrentVersion(); } // We first check streams in cache, then try to load. ManagedTypedStream stream = GetCachedTypedStream(t.FullName, mode); if (stream != null) { return(stream); } // We can also check in base node. ManagedNode b = CacheBase(); if (b != null) { return(b.GetTypedStream(mode, t)); } return(null); } }
/// <summary> /// We delete a specific version. /// </summary> /// <param name="node">The node.</param> /// <param name="version">The version.</param> public void DeleteVersion(IDriverNode node, ulong version) { if (currentVersion.Version == version) { throw new InvalidOperationException("Cannot delete current version."); } // We make sure we lose references. WeakReference versionRef; if (versions.TryGetValue(version, out versionRef)) { ManagedNode v = versionRef.Target as ManagedNode; if (v != null) { // Cannot be used anymore! v.Dispose(); } versions.Remove(version); } // And issue delete. node.DeleteVersion(version); }
/// <summary> /// Previouses the version. /// </summary> /// <param name="thisVersion">The this version.</param> /// <returns></returns> public ManagedNode PreviousVersion(ulong thisVersion) { if (thisVersion == 0) { return(null); } // We search for nearest previous version. for (ulong v = thisVersion - 1; v >= 0;) { WeakReference versionRef; if (versions.TryGetValue(v, out versionRef)) { ManagedNode prevVersion = versionRef.Target as ManagedNode; if (prevVersion != null) { return(prevVersion); } } if (v == 0) { break; } } // No previous version. return(null); }
/// <summary> /// Creates the new version. /// </summary> /// <param name="type">The type.</param> /// <param name="options">The options.</param> /// <returns></returns> public ManagedNode CreateNewVersion(IDriverNode node, string type, StreamOptions options) { IDriverNode newVersionNode = node.CreateNewVersion(type, options); // We now add it to current. ulong ver = currentVersion.Version + 1; currentVersion = new ManagedNode(newVersionNode, ver, this); versions.Add(ver, new WeakReference(currentVersion)); // And return it. return(currentVersion); }
public void Dispose() { lock (SyncRoot) { foreach (KeyValuePair <ulong, WeakReference> v in versions) { ManagedNode node = v.Value.Target as ManagedNode; if (node != null) { node.Dispose(); } } } }
public void UnMount(string path) { lock (mounts) { if (mounts.Remove(path)) { ManagedNode node = root.Find(path) as ManagedNode; node.SetAsMountNode(null); } else { throw new UnMountException("The path " + path + " is not a mount point, cannot be unmounted."); } } }
public ManagedCommonNode(ManagedCommonNode parent, string name, IDriverNode driverNode, ManagedDatabaseManager manager) { ulong version = 1; if (driverNode != null) { version = driverNode.Version; } this.parent = parent; this.name = name; this.manager = manager; this.currentVersion = new ManagedNode(driverNode, version, this); this.versions[version] = new WeakReference(this.currentVersion); }
/// <summary> /// Caches base node, if not already cached. /// </summary> private ManagedNode CacheBase() { // We must quickly open default tag stream, if it exists. using (IDriverTypedStream stream = node.GetTypedStream(OpenMode.ReadWrite, typeof(BaseNodeTag).FullName)) { // Make sure we proceed this read only once. if (stream == null) { return(null); } // Now we find the type. BaseNodeTag tag = stream.UsesRaw ? Common.DeserializeObject(stream.Read(0) as byte[]) as BaseNodeTag : stream.Read(0) as BaseNodeTag; // We find the link. ManagedNode baseCached = common.Manager.Find(tag.Link) as ManagedNode; // Avoid processing once more. if (baseCached == null) { // We do not reset it because it can be mounted in future. throw new NodeNotFoundException("The base node " + tag.ToString() + " could not be found."); } // Must also take version into account. if (tag.Version != ulong.MaxValue) { baseCached = baseCached[tag.Version] as ManagedNode; if (baseCached == null) { throw new NodeNotFoundException("The base node " + tag.ToString() + " could not be found."); } } return(baseCached); } }
/// <summary> /// Finds the node and if it does not exist, it creates it. /// </summary> /// <param name="path">The path.</param> /// <returns>Managed node at path (constructed).</returns> internal ManagedNode FindOrCreate(int i, string[] path) { // We resolved the whole path. if (path.Length == i) { return(this); } lock (SyncRoot) { AssertNotDisposed(); ManagedNode redirect = common.GetChild(node, path[i]); // We must create transparent node. if (redirect == null) { redirect = common.CreateTransparent(path[i]); } // We remove processed string. return(redirect.FindOrCreate(i + 1, path)); } }
/// <summary> /// Finds a version. /// </summary> /// <param name="id">The version id.</param> /// <returns>Managed node around the version.</returns> public ManagedNode GetVersion(IDriverNode n, ulong id) { // We search in cachd first: WeakReference versionRef; if (versions.TryGetValue(id, out versionRef)) { ManagedNode version = versionRef.Target as ManagedNode; // Can be dereferenced in between. if (version != null) { return(version); } } // We cannot create it if node does not exist. if (n == null) { return(null); } // We read it from driver. IDriverNode vn = n.GetVersion(id); if (vn == null) { return(null); } // We create it, add to cache and return it. ManagedNode versionNode = new ManagedNode(vn, id, this); versions[id] = new WeakReference(versionNode); return(versionNode); }
/// <summary> /// Database manager construction. /// </summary> public ManagedDatabaseManager() { root = ManagedNode.CreateNew(this); }
public INode CopyTo([NotNull] INode n) { lock (SyncRoot) { AssertNotDisposed(); // Must ensure from the same db and other checks. ManagedNode dest = n as ManagedNode; // We check if we are not moving to child of our node. string pathTo = dest.Path; string pathFrom = Path; if (pathTo.Length > pathFrom.Length && pathTo.Substring(0, pathFrom.Length) == pathFrom) { throw new InvalidOperationException(string.Format("Moving from path {0} to " + "path {1} which is a child of path {0}", pathFrom, pathTo)); } // We create it with default type. INode myCopy; using (ITypedStream defaultTS = OpenDefaultStream(OpenMode.Read)) { myCopy = dest.CreateChild(Name, defaultTS.StreamType, defaultTS.Flags); // Copy data. using (ITypedStream defaultCopyTS = myCopy.OpenDefaultStream(OpenMode.Write)) { defaultTS.CopyTo(defaultCopyTS); } } // All typed streams. foreach (Type t in TypedStreams) { // Default type already handled. if (t == DefaultType) { continue; } using (ITypedStream ts = GetTypedStream(OpenMode.Read, t)) { // Copy data. myCopy.AddTypedStream(ts.StreamType, ts.Flags); using (ITypedStream tsCopy = myCopy.GetTypedStream(OpenMode.Write, ts.StreamType)) { ts.CopyTo(tsCopy); } } } // And all children at last. foreach (string s in Children) { INode child = this.Find(s); child.CopyTo(myCopy); } return(myCopy); } }
public INode Find(string inPath) { // First validate path. if (!PathHelper.ValidatePath(ref inPath)) { throw new InvalidPathException("The path " + inPath + " is invalid."); } // A special case of root linking. if (inPath == PathHelper.Slash) { return(common.Manager.Root); } // We do processing out of lock if possible. string part; string path = PathHelper.SeperatePath(inPath, out part); // We process root links. if (path == string.Empty) { if (part == null) { return(common.Manager.Root); } return(common.Manager.Find(part)); } // We process back links. if (path == PathHelper.ParentLink) { // Cannot find it. if (common.Parent == null) { return(null); } if (part == null) { return(common.Parent.CurrentVersion); } else { return(common.Parent.CurrentVersion.Find(part)); } } lock (SyncRoot) { AssertNotDisposed(); ManagedNode child = common.GetChild(node, path); // We check if child cannot be found. if (child == null) { ManagedNode b = CacheBase(); if (b != null) { return(b.Find(inPath)); } // Cannot be found. return(null); } else { // We return child if no more to search. if (part == null) { return(child); } return(child.Find(part)); } } }
/// <summary> /// Renames the specified child. /// </summary> public void RenameChildNoLock(string name, ManagedNode child, string newName) { children.Remove(name); children.Add(newName, new WeakReference(child)); }