Exemplo n.º 1
0
        public void can_look_up_paths_by_value_from_serialised_data()
        {
            // you can assign the same value to multiple paths
            // this could be quite useful, but I'd like to be able to
            // reverse the process -- see what paths an objects is bound
            // to. Could be a simple set of scans (slow) or a restructuring
            // of the internal data.

            var source = new ReverseTrie <ByteString>();

            source.Add("very different", "value0");
            source.Add("my/path/1", "value1");
            source.Add("my/path/2", "value2");
            source.Add("b - very different", "value0");
            source.Add("my/other/path", "value3");
            source.Add("my/other/path/longer", "value4");
            source.Add("another/path/for/3", "value3");
            source.Add("z - very different", "value0");

            var bytes         = source.Freeze();
            var reconstituted = new ReverseTrie <ByteString>();

            bytes.Seek(0, SeekOrigin.Begin);
            reconstituted.Defrost(bytes);

            var result = string.Join(", ", reconstituted.GetPathsForEntry("value3"));

            Assert.That(result, Is.EqualTo("my/other/path, another/path/for/3"));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Remove a path binding if it exists. If the path is not bound, nothing happens.
        /// Linked documents are not removed.
        /// </summary>
        public void UnbindPath(string exactPath)
        {
            _pathLookupCache = null;
            lock (_fslock)
            {
                var pathLink  = GetPathLookupLink();
                var pathIndex = new ReverseTrie <SerialGuid>();
                if (!pathLink.TryGetLink(0, out var pathPageId))
                {
                    return;
                }
                pathIndex.Defrost(GetStream(pathPageId));

                // Unbind the path
                pathIndex.Delete(exactPath);

                // Write back to new chain
                var newPageId = WriteStream(pathIndex.Freeze());

                // Update version link
                pathLink.WriteNewLink(newPageId, out var expired);
                SetPathLookupLink(pathLink);

                ReleaseChain(expired);
                Flush();
            }
        }
Exemplo n.º 3
0
        [NotNull] private ReverseTrie <SerialGuid> GetPathLookupIndex()
        {
            var pathIndex = _pathLookupCache;

            if (pathIndex != null)
            {
                return(pathIndex);
            }

            lock (_fslock)
            {
                var pathLink = GetPathLookupLink();
                pathIndex = new ReverseTrie <SerialGuid>();
                if (pathLink.TryGetLink(0, out var pathPageId))
                {
                    pathIndex.Defrost(GetStream(pathPageId));
                }
                _pathLookupCache = pathIndex;
            }

            return(pathIndex);
        }
Exemplo n.º 4
0
        public void serialisation_and_restoring()
        {
            var subject   = new ReverseTrie <ByteString>();
            var rawLength = 0;

            // Fill it up
            for (int i = 0; i < 100; i++)
            {
                var key   = $"Path number {i}";
                var value = $"{i}";

                rawLength += key.Length + value.Length;

                subject.Add(key, ByteString.Wrap(value));
            }

            var frozen = subject.Freeze();

            frozen.Seek(0, SeekOrigin.Begin);

            Console.WriteLine($"Encoding 100 paths in {frozen.Length} bytes. Raw input was {rawLength} bytes");
            Console.WriteLine(frozen.ToHexString());
            subject = null;

            var result = new ReverseTrie <ByteString>();

            frozen.Seek(0, SeekOrigin.Begin);
            result.Defrost(frozen);

            // Check every result
            for (int i = 0; i < 100; i++)
            {
                var key      = $"Path number {i}";
                var expected = $"{i}";
                Assert.That(result.Get(key)?.ToString(), Is.EqualTo(expected), $"Lost data at path '{key}'");
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Bind an exact path to a document ID.
        /// If an existing document was bound to the same path, its ID will be returned
        /// </summary>
        /// <param name="path">Exact path for document</param>
        /// <param name="documentId">new document id</param>
        /// <param name="previousDocId">old document id that has been replaced, if any.</param>
        public void BindPath(string path, Guid documentId, out Guid?previousDocId)
        {
            previousDocId = null;
            if (string.IsNullOrEmpty(path))
            {
                throw new Exception("Path must not be null or empty");
            }
            _pathLookupCache = null;

            lock (_fslock)
            {
                // Read current path document (if it exists)
                var pathLink  = GetPathLookupLink();
                var pathIndex = new ReverseTrie <SerialGuid>();
                if (pathLink.TryGetLink(0, out var pathPageId))
                {
                    pathIndex.Defrost(GetStream(pathPageId));
                }

                // Bind the path
                var serialGuid = pathIndex.Add(path, documentId);
                if (serialGuid != null)
                {
                    previousDocId = serialGuid.Value;
                }

                // Write back to new chain
                var newPageId = WriteStream(pathIndex.Freeze());

                // Update version link
                pathLink.WriteNewLink(newPageId, out var expired);
                SetPathLookupLink(pathLink);

                ReleaseChain(expired);
                Flush();
            }
        }