예제 #1
0
        public bool ReadKey(BTreeValue *pEntry, ushort keyType, out TangleKey key)
        {
            if (keyType == 0)
            {
                key = default(TangleKey);
                return(false);
            }

            var buffer = ImmutableArrayPool <byte> .Allocate(pEntry->KeyLength);

            if (pEntry->KeyLength <= BTreeValue.KeyPrefixSize)
            {
                fixed(byte *pBuffer = buffer.Array)
                Native.memmove(pBuffer + buffer.Offset, pEntry->KeyPrefix, new UIntPtr(pEntry->KeyLength));
            }
            else
            {
                using (var keyRange = KeyStream.AccessRange(
                           pEntry->KeyOffset, pEntry->KeyLength, MemoryMappedFileAccess.Read
                           ))
                    Unsafe.ReadBytes(keyRange.Pointer, 0, buffer.Array, buffer.Offset, pEntry->KeyLength);
            }

            key = new TangleKey(buffer, keyType);
            return(true);
        }
예제 #2
0
        public void NumericKeysWork()
        {
            var key = new TangleKey(1234);

            Scheduler.WaitFor(Tangle.Set(key, 1));
            Assert.AreEqual(1, Scheduler.WaitFor(Tangle.Get(key)));
        }
예제 #3
0
        public void UsesStaticSerializerAndDeserializerMethodsAutomatically()
        {
            var key = new TangleKey("hello");

            Scheduler.WaitFor(Tangle.Set(key, new SpecialType(key, 4)));
            var result = Scheduler.WaitFor(Tangle.Get("hello"));

            Assert.AreEqual(4, result.Value);
        }
예제 #4
0
        public void TestRepeatedGrowAndShrink()
        {
            var wasted1 = Tangle.WastedDataBytes;

            for (int i = 1; i < 50; i += 10)
            {
                for (int j = 0; j < 20; j++)
                {
                    var key  = new TangleKey(String.Format("test{0}", j));
                    var text = new String((char)(j + 63), i);

                    Scheduler.WaitFor(Tangle.Set(key, text));

                    Assert.AreEqual(
                        text, Scheduler.WaitFor(Tangle.Get(key))
                        );
                }
            }

            var wasted2 = Tangle.WastedDataBytes;

            Assert.Greater(wasted2, wasted1);

            for (int j = 0; j < 20; j++)
            {
                var key  = new TangleKey(String.Format("test{0}", j));
                var text = new String((char)(j + 63), 5);

                Scheduler.WaitFor(Tangle.Set(key, text));

                Assert.AreEqual(
                    text, Scheduler.WaitFor(Tangle.Get(key))
                    );
            }

            var wasted3 = Tangle.WastedDataBytes;

            Assert.AreEqual(wasted3, wasted2);

            for (int j = 20; j < 40; j++)
            {
                var key  = new TangleKey(String.Format("test{0}", j));
                var text = new String((char)(j + 63), 10);

                Scheduler.WaitFor(Tangle.Set(key, text));

                Assert.AreEqual(
                    text, Scheduler.WaitFor(Tangle.Get(key))
                    );
            }

            // This will fail if the freelist is not being used
            Assert.Less(Tangle.WastedDataBytes, wasted3, "Freelist not functioning");
        }
예제 #5
0
        public void IndexUpdatedWhenAddingNewValues()
        {
            var ByValue = Scheduler.WaitFor(Tangle.CreateIndex("ByValue", (ref string v) => v));

            var key   = new TangleKey("hello");
            var value = "world";

            Scheduler.WaitFor(Tangle.Set(key, value));

            Assert.AreEqual(key, Scheduler.WaitFor(ByValue.FindOne(value)));
            Assert.AreEqual(value, Scheduler.WaitFor(ByValue.GetOne(value)));
        }
예제 #6
0
        public void WriteKey(ref BTreeValue btreeValue, TangleKey key)
        {
            var prefixSize = Math.Min(key.Data.Count, BTreeValue.KeyPrefixSize);

            fixed(byte *pPrefix = btreeValue.KeyPrefix)
            Unsafe.WriteBytes(pPrefix, 0, key.Data.Array, key.Data.Offset, prefixSize);

            if (prefixSize < key.Data.Count)
            {
                using (var keyRange = KeyStream.AccessRange(btreeValue.KeyOffset, btreeValue.KeyLength, MemoryMappedFileAccess.Write))
                    Unsafe.WriteBytes(keyRange.Pointer, 0, key.Data);
            }
        }
예제 #7
0
        public void TestKeyEquals()
        {
            var keyA = new TangleKey("abcd");
            var keyB = new TangleKey("abcd");
            var keyC = new TangleKey(2);
            var keyD = new TangleKey(2);

            Assert.IsTrue(keyA.Equals(keyA));
            Assert.IsTrue(keyA.Equals(keyB));
            Assert.IsTrue(keyC.Equals(keyC));
            Assert.IsTrue(keyC.Equals(keyD));
            Assert.IsFalse(keyA.Equals(keyC));
        }
예제 #8
0
        public void CanAddIndexToTangleWithExistingValues()
        {
            var key1 = new TangleKey("hello");
            var value1 = "world";
            var key2 = new TangleKey("greetings");
            var value2 = "place";

            Scheduler.WaitFor(Tangle.Set(key1, value1));
            Scheduler.WaitFor(Tangle.Set(key2, value2));

            var ByValue = Scheduler.WaitFor(Tangle.CreateIndex("ByValue", (ref string v) => v));

            Assert.AreEqual(key1, Scheduler.WaitFor(ByValue.FindOne(value1)));
            Assert.AreEqual(key2, Scheduler.WaitFor(ByValue.FindOne(value2)));
        }
예제 #9
0
        public void CanAddIndexToTangleWithExistingValues()
        {
            var key1   = new TangleKey("hello");
            var value1 = "world";
            var key2   = new TangleKey("greetings");
            var value2 = "place";

            Scheduler.WaitFor(Tangle.Set(key1, value1));
            Scheduler.WaitFor(Tangle.Set(key2, value2));

            var ByValue = Scheduler.WaitFor(Tangle.CreateIndex("ByValue", (ref string v) => v));

            Assert.AreEqual(key1, Scheduler.WaitFor(ByValue.FindOne(value1)));
            Assert.AreEqual(key2, Scheduler.WaitFor(ByValue.FindOne(value2)));
        }
예제 #10
0
        public void IndexHandlesMultipleKeysForTheSameValue()
        {
            var ByValue = Scheduler.WaitFor(Tangle.CreateIndex("ByValue", (ref string v) => v));

            var key1  = new TangleKey("hello");
            var key2  = new TangleKey("greetings");
            var value = "world";

            Scheduler.WaitFor(Tangle.Set(key1, value));
            Scheduler.WaitFor(Tangle.Set(key2, value));

            Assert.AreEqual(
                new TangleKey[] { key1, key2 },
                Scheduler.WaitFor(ByValue.Find(value))
                );
            Assert.AreEqual(
                new string[] { value, value },
                Scheduler.WaitFor(ByValue.Get(value))
                );
        }
예제 #11
0
        public void FetchKeysForMultipleValuesWithEnumeratorIndex()
        {
            var ByWords = Scheduler.WaitFor(Tangle.CreateIndex <string>(
                                                "ByWords",
                                                (string v) => v.Split(' ')
                                                ));

            var key1   = new TangleKey("a");
            var key2   = new TangleKey("b");
            var value1 = "Hello World";
            var value2 = "Greetings World";

            Scheduler.WaitFor(Tangle.Set(key1, value1));
            Scheduler.WaitFor(Tangle.Set(key2, value2));

            Assert.AreEqual(
                new[] { key1, key2 },
                Scheduler.WaitFor(ByWords.Find(new [] { "Hello", "Greetings" }))
                );
        }
예제 #12
0
        public void CanUseEnumeratorAsIndexFunction()
        {
            // Bleh, unless we explicitly specify the type argument to CreateIndex,
            //  it assumes a type of <string[]> instead of picking the IEnumerable overload.
            var ByWords = Scheduler.WaitFor(Tangle.CreateIndex <string>(
                                                "ByWords",
                                                (string v) => v.Split(' ')
                                                ));

            var key1   = new TangleKey("a");
            var key2   = new TangleKey("b");
            var value1 = "Hello World";
            var value2 = "Greetings World";

            Scheduler.WaitFor(Tangle.Set(key1, value1));
            Scheduler.WaitFor(Tangle.Set(key2, value2));

            Assert.AreEqual(new [] { key1, key2 }, Scheduler.WaitFor(ByWords.Find("World")));
            Assert.AreEqual(new [] { key2 }, Scheduler.WaitFor(ByWords.Find("Greetings")));
        }
예제 #13
0
        public unsafe void TestGrowAndAlterDataByLockingIt()
        {
            var key      = new TangleKey("test");
            var value    = "abcdefgh";
            var newValue = "acdefghijkl";

            Scheduler.WaitFor(Tangle.Set(key, value));

            var findResult = Scheduler.WaitFor(Tangle.Find(key));
            var newBytes   = Encoding.UTF8.GetBytes(newValue);

            fixed(byte *pNewBytes = newBytes)
            using (var data = Scheduler.WaitFor(findResult.LockData(newBytes.Length)))
            {
                Assert.GreaterOrEqual(data.Size, newBytes.Length);
                Native.memmove(data.Pointer, pNewBytes, new UIntPtr((uint)newBytes.Length));
            }

            Assert.AreEqual(newValue, Scheduler.WaitFor(Tangle.Get(key)));
        }
예제 #14
0
        public unsafe void TestLockExistingData()
        {
            var key   = new TangleKey("test");
            var value = "abcdefgh";

            Scheduler.WaitFor(Tangle.Set(key, value));

            var findResult    = Scheduler.WaitFor(Tangle.Find(key));
            var expectedBytes = Encoding.UTF8.GetBytes(value);

            fixed(byte *pExpected = expectedBytes)
            using (var data = Scheduler.WaitFor(findResult.LockData()))
            {
                Assert.AreEqual(expectedBytes.Length, data.Size);
                Assert.AreEqual(0, Native.memcmp(
                                    pExpected, data.Pointer,
                                    new UIntPtr((uint)Math.Min(data.Size, expectedBytes.Length))
                                    ));
            }
        }
예제 #15
0
        public void CanUseEnumeratorAsIndexFunction()
        {
            // Bleh, unless we explicitly specify the type argument to CreateIndex,
            //  it assumes a type of <string[]> instead of picking the IEnumerable overload.
            var ByWords = Scheduler.WaitFor(Tangle.CreateIndex<string>(
                "ByWords",
                (string v) => v.Split(' ')
            ));

            var key1 = new TangleKey("a");
            var key2 = new TangleKey("b");
            var value1 = "Hello World";
            var value2 = "Greetings World";

            Scheduler.WaitFor(Tangle.Set(key1, value1));
            Scheduler.WaitFor(Tangle.Set(key2, value2));

            Assert.AreEqual(new [] { key1, key2 }, Scheduler.WaitFor(ByWords.Find("World")));
            Assert.AreEqual(new [] { key2 }, Scheduler.WaitFor(ByWords.Find("Greetings")));
        }
예제 #16
0
        public void TestCopyDataToStream()
        {
            var key   = new TangleKey("test");
            var value = new String('a', 1024 * 1024 * 2);

            Scheduler.WaitFor(Tangle.Set(key, value));

            var findResult = Scheduler.WaitFor(Tangle.Find(key));
            var ms         = new MemoryStream();

            Scheduler.WaitFor(findResult.CopyTo(ms, bufferSize: 64 * 1024));

            var expectedBytes = Encoding.UTF8.GetBytes(value);
            var actualBytes   = new byte[expectedBytes.Length];

            ms.Seek(0, SeekOrigin.Begin);
            ms.Read(actualBytes, 0, expectedBytes.Length);

            Assert.AreEqual(expectedBytes, actualBytes);
        }
예제 #17
0
        public void WriteNewKey(BTreeValue *pEntry, TangleKey key)
        {
            if (key.Data.Count > BTreeValue.KeyPrefixSize)
            {
                pEntry->KeyOffset = (uint)KeyStream.AllocateSpace((uint)key.Data.Count).Value;
            }
            else
            {
                pEntry->KeyOffset = 0;
            }

            pEntry->KeyLength = (ushort)key.Data.Count;

            // It's important that we zero out these fields so that when we write the data,
            //  it's done in append mode instead of replace mode
            pEntry->DataOffset     = 0;
            pEntry->DataLength     = 0;
            pEntry->ExtraDataBytes = 0;

            WriteKey(ref *pEntry, key);
        }
예제 #18
0
        public void SerializerAndDeserializerHaveAccessToKey()
        {
            var key = new TangleKey("hello");

            // This will fail because the specified keys don't match, and that lets us know
            //  that the serializer had access to the key. Kind of a hack.
            try {
                Scheduler.WaitFor(Tangle.Set("world", new SpecialType(key, 4)));
            } catch (FutureException fe) {
                Assert.IsInstanceOf <SerializerThrewException>(fe.InnerException);
                Assert.IsInstanceOf <InvalidDataException>(fe.InnerException.InnerException);
            }

            // As a side effect, this also tests the Tangle's ability to recover from
            //  a failed serialization. If an exception from the Serializer were to bubble
            //  up, the BTree would be left in an invalid state and this set would fail.
            Scheduler.WaitFor(Tangle.Set(key, new SpecialType(key, 4)));

            var result = Scheduler.WaitFor(Tangle.Get("hello"));

            Assert.IsTrue(key.Equals(result.Key));
        }
예제 #19
0
        public void IndexUpdatedWhenValueChanged()
        {
            var ByValue = Scheduler.WaitFor(Tangle.CreateIndex("ByValue", (ref string v) => v));

            var key    = new TangleKey("hello");
            var value1 = "world";
            var value2 = "place";

            Scheduler.WaitFor(Tangle.Set(key, value1));

            Assert.AreEqual(key, Scheduler.WaitFor(ByValue.FindOne(value1)));

            Scheduler.WaitFor(Tangle.Set(key, value2));

            try {
                Scheduler.WaitFor(ByValue.FindOne(value1));
                Assert.Fail("Expected to throw");
            } catch (FutureException fe) {
                Assert.IsInstanceOf <KeyNotFoundException>(fe.InnerException);
            }

            Assert.AreEqual(key, Scheduler.WaitFor(ByValue.FindOne(value2)));
        }
예제 #20
0
        public void TestGetAllKeys()
        {
            var ByWords = Scheduler.WaitFor(Tangle.CreateIndex <string>(
                                                "ByWords",
                                                (string v) => v.Split(' ')
                                                ));

            var key1   = new TangleKey("a");
            var key2   = new TangleKey("b");
            var value1 = "Hello World";
            var value2 = "Greetings World";

            Scheduler.WaitFor(Tangle.Set(key1, value1));
            Scheduler.WaitFor(Tangle.Set(key2, value2));

            Assert.AreEqual(
                new[] { "Greetings", "Hello", "World" },
                Scheduler.WaitFor(ByWords.GetAllKeys())
                .Select((k) => k.Value as string)
                .OrderBy((k) => k)
                .ToArray()
                );
        }
예제 #21
0
        public void FetchKeysForMultipleValues()
        {
            var ByValue = Scheduler.WaitFor(Tangle.CreateIndex("ByValue", (ref string v) => v));

            var key1   = new TangleKey("hello");
            var key2   = new TangleKey("greetings");
            var key3   = new TangleKey("hi");
            var value1 = "world";
            var value2 = "cat";

            Scheduler.WaitFor(Tangle.Set(key1, value1));
            Scheduler.WaitFor(Tangle.Set(key2, value1));
            Scheduler.WaitFor(Tangle.Set(key3, value2));

            Assert.AreEqual(
                new TangleKey[] { key1, key2, key3 },
                Scheduler.WaitFor(ByValue.Find(new[] { value1, value2 }))
                );
            Assert.AreEqual(
                new string[] { value1, value1, value2 },
                Scheduler.WaitFor(ByValue.Get(new [] { value1, value2 }))
                );
        }
예제 #22
0
        public void FetchKeysForMultipleValuesWithEnumeratorIndex()
        {
            var ByWords = Scheduler.WaitFor(Tangle.CreateIndex<string>(
                "ByWords",
                (string v) => v.Split(' ')
            ));

            var key1 = new TangleKey("a");
            var key2 = new TangleKey("b");
            var value1 = "Hello World";
            var value2 = "Greetings World";

            Scheduler.WaitFor(Tangle.Set(key1, value1));
            Scheduler.WaitFor(Tangle.Set(key2, value2));

            Assert.AreEqual(
                new[] { key1, key2 },
                Scheduler.WaitFor(ByWords.Find(new [] { "Hello", "Greetings" }))
            );
        }
예제 #23
0
        /// <summary>
        /// Searches the BTree for a provided key.
        /// </summary>
        /// <param name="key">The key to search for.</param>
        /// <param name="forInsertion">Indicates that you will be inserting the specified key if it does not already exist. If true, the find operation will prepare the tree for an insert operation.</param>
        /// <param name="nodeIndex">Contains the index of the BTree node where the search ended.</param>
        /// <param name="valueIndex">Contains the index of the value within the node that matched the key, if a match was found. If a match was not found, contains the index of the leaf where the key should be inserted.</param>
        /// <returns>True if the key was found within the tree. False if the key was not found.</returns>
        public bool FindKey(TangleKey key, bool forInsertion, out long nodeIndex, out uint valueIndex)
        {
            uint keyLength = (uint)key.Data.Count;

            long rootIndex        = RootIndex;
            long parentNodeIndex  = rootIndex;
            long currentNode      = parentNodeIndex;
            uint parentValueIndex = 0;

            while (true)
                fixed(byte *pKey = &key.Data.Array[key.Data.Offset])
                using (var range = AccessNode(currentNode, false))
                {
                    var pNode = (BTreeNode *)range.Pointer;

                    // As we descend the tree, we split any full nodes we encounter so that
                    //  if we end up performing an insertion, we won't need to then walk all the
                    //  way back *up* the tree and split in reverse.
                    if (forInsertion && (pNode->NumValues == BTreeNode.MaxValues))
                    {
                        if (parentNodeIndex == currentNode)
                        {
                            // Splitting the root.
                            var newRootIndex = CreateRoot();

                            using (var newRootRange = AccessNode(newRootIndex, true)) {
                                var pNewRoot   = (BTreeNode *)newRootRange.Pointer;
                                var pNewLeaves = (BTreeLeaf *)(newRootRange.Pointer + BTreeNode.OffsetOfLeaves);

                                // This looks wrong, but it's not: We want the new root to contain 0 values,
                                //  but have one leaf pointing to the old root, so that we can split the old
                                //  root in half. Splitting will move a single value up into the new root.
                                pNewRoot->HasLeaves     = 1;
                                pNewLeaves[0].NodeIndex = (uint)currentNode;

                                UnlockNode(newRootRange);
                            }

                            SplitLeafNode(newRootIndex, 0, currentNode);

                            // Restart at the root
                            currentNode      = parentNodeIndex = rootIndex = newRootIndex;
                            parentValueIndex = 0;
                            continue;
                        }
                        else
                        {
                            // Splitting a regular node.
                            SplitLeafNode(parentNodeIndex, parentValueIndex, currentNode);

                            // Restart at the root
                            currentNode      = parentNodeIndex = rootIndex;
                            parentValueIndex = 0;
                            continue;
                        }
                    }

                    var pValues = (BTreeValue *)(range.Pointer + BTreeNode.OffsetOfValues);

                    if (SearchValues(pValues, pNode->NumValues, pKey, keyLength, out valueIndex))
                    {
                        // Found an exact match within the BTree node.
                        nodeIndex = currentNode;
                        return(true);
                    }

                    if (pNode->HasLeaves == 1)
                    {
                        // No exact match was found, so valueIndex now contains the index of the leaf node.
                        var pLeaves = (BTreeLeaf *)(range.Pointer + BTreeNode.OffsetOfLeaves);

                        parentNodeIndex  = currentNode;
                        parentValueIndex = valueIndex;

                        currentNode = pLeaves[valueIndex].NodeIndex;
                    }
                    else
                    {
                        // The value was not found inside the node, and we're in a node with no leaves, so there is no match.
                        nodeIndex = currentNode;
                        return(false);
                    }
                }
        }
예제 #24
0
        public unsafe void TestLockExistingData()
        {
            var key = new TangleKey("test");
            var value = "abcdefgh";
            Scheduler.WaitFor(Tangle.Set(key, value));

            var findResult = Scheduler.WaitFor(Tangle.Find(key));
            var expectedBytes = Encoding.UTF8.GetBytes(value);

            fixed (byte * pExpected = expectedBytes)
            using (var data = Scheduler.WaitFor(findResult.LockData())) {
                Assert.AreEqual(expectedBytes.Length, data.Size);
                Assert.AreEqual(0, Native.memcmp(
                    pExpected, data.Pointer,
                    new UIntPtr((uint)Math.Min(data.Size, expectedBytes.Length))
                ));
            }
        }
예제 #25
0
        public void IndexUpdatedWhenValueChanged()
        {
            var ByValue = Scheduler.WaitFor(Tangle.CreateIndex("ByValue", (ref string v) => v));

            var key = new TangleKey("hello");
            var value1 = "world";
            var value2 = "place";

            Scheduler.WaitFor(Tangle.Set(key, value1));

            Assert.AreEqual(key, Scheduler.WaitFor(ByValue.FindOne(value1)));

            Scheduler.WaitFor(Tangle.Set(key, value2));

            try {
                Scheduler.WaitFor(ByValue.FindOne(value1));
                Assert.Fail("Expected to throw");
            } catch (FutureException fe) {
                Assert.IsInstanceOf<KeyNotFoundException>(fe.InnerException);
            }

            Assert.AreEqual(key, Scheduler.WaitFor(ByValue.FindOne(value2)));
        }
예제 #26
0
        public void TestCopyDataToStream()
        {
            var key = new TangleKey("test");
            var value = new String('a', 1024 * 1024 * 2);

            Scheduler.WaitFor(Tangle.Set(key, value));

            var findResult = Scheduler.WaitFor(Tangle.Find(key));
            var ms = new MemoryStream();

            Scheduler.WaitFor(findResult.CopyTo(ms, bufferSize: 64 * 1024));

            var expectedBytes = Encoding.UTF8.GetBytes(value);
            var actualBytes = new byte[expectedBytes.Length];

            ms.Seek(0, SeekOrigin.Begin);
            ms.Read(actualBytes, 0, expectedBytes.Length);

            Assert.AreEqual(expectedBytes, actualBytes);
        }
예제 #27
0
        public void WriteNewKey(StreamRange nodeRange, uint valueIndex, TangleKey key)
        {
            long position = BTreeNode.OffsetOfValues + (valueIndex * BTreeValue.Size);

            WriteNewKey((BTreeValue *)(nodeRange.Pointer + position), key);
        }
예제 #28
0
        public unsafe void TestGrowAndAlterDataByLockingIt()
        {
            var key = new TangleKey("test");
            var value = "abcdefgh";
            var newValue = "acdefghijkl";
            Scheduler.WaitFor(Tangle.Set(key, value));

            var findResult = Scheduler.WaitFor(Tangle.Find(key));
            var newBytes = Encoding.UTF8.GetBytes(newValue);

            fixed (byte* pNewBytes = newBytes)
            using (var data = Scheduler.WaitFor(findResult.LockData(newBytes.Length))) {
                Assert.GreaterOrEqual(data.Size, newBytes.Length);
                Native.memmove(data.Pointer, pNewBytes, new UIntPtr((uint)newBytes.Length));
            }

            Assert.AreEqual(newValue, Scheduler.WaitFor(Tangle.Get(key)));
        }
예제 #29
0
        public void IndexHandlesMultipleKeysForTheSameValue()
        {
            var ByValue = Scheduler.WaitFor(Tangle.CreateIndex("ByValue", (ref string v) => v));

            var key1 = new TangleKey("hello");
            var key2 = new TangleKey("greetings");
            var value = "world";

            Scheduler.WaitFor(Tangle.Set(key1, value));
            Scheduler.WaitFor(Tangle.Set(key2, value));

            Assert.AreEqual(
                new TangleKey[] { key1, key2 },
                Scheduler.WaitFor(ByValue.Find(value))
            );
            Assert.AreEqual(
                new string[] { value, value },
                Scheduler.WaitFor(ByValue.Get(value))
            );
        }
예제 #30
0
        public void TestKeyEquals()
        {
            var keyA = new TangleKey("abcd");
            var keyB = new TangleKey("abcd");
            var keyC = new TangleKey(2);
            var keyD = new TangleKey(2);

            Assert.IsTrue(keyA.Equals(keyA));
            Assert.IsTrue(keyA.Equals(keyB));
            Assert.IsTrue(keyC.Equals(keyC));
            Assert.IsTrue(keyC.Equals(keyD));
            Assert.IsFalse(keyA.Equals(keyC));
        }
예제 #31
0
        public void IndexUpdatedWhenAddingNewValues()
        {
            var ByValue = Scheduler.WaitFor(Tangle.CreateIndex("ByValue", (ref string v) => v));

            var key = new TangleKey("hello");
            var value = "world";

            Scheduler.WaitFor(Tangle.Set(key, value));

            Assert.AreEqual(key, Scheduler.WaitFor(ByValue.FindOne(value)));
            Assert.AreEqual(value, Scheduler.WaitFor(ByValue.GetOne(value)));
        }
예제 #32
0
        public void FetchKeysForMultipleValues()
        {
            var ByValue = Scheduler.WaitFor(Tangle.CreateIndex("ByValue", (ref string v) => v));

            var key1 = new TangleKey("hello");
            var key2 = new TangleKey("greetings");
            var key3 = new TangleKey("hi");
            var value1 = "world";
            var value2 = "cat";

            Scheduler.WaitFor(Tangle.Set(key1, value1));
            Scheduler.WaitFor(Tangle.Set(key2, value1));
            Scheduler.WaitFor(Tangle.Set(key3, value2));

            Assert.AreEqual(
                new TangleKey[] { key1, key2, key3 },
                Scheduler.WaitFor(ByValue.Find(new[] { value1, value2 }))
            );
            Assert.AreEqual(
                new string[] { value1, value1, value2 },
                Scheduler.WaitFor(ByValue.Get(new [] { value1, value2 }))
            );
        }
예제 #33
0
        public void TestGetAllKeys()
        {
            var ByWords = Scheduler.WaitFor(Tangle.CreateIndex<string>(
                "ByWords",
                (string v) => v.Split(' ')
            ));

            var key1 = new TangleKey("a");
            var key2 = new TangleKey("b");
            var value1 = "Hello World";
            var value2 = "Greetings World";

            Scheduler.WaitFor(Tangle.Set(key1, value1));
            Scheduler.WaitFor(Tangle.Set(key2, value2));

            Assert.AreEqual(
                new[] { "Greetings", "Hello", "World" },
                Scheduler.WaitFor(ByWords.GetAllKeys())
                    .Select((k) => k.Value as string)
                    .OrderBy((k) => k)
                    .ToArray()
            );
        }
예제 #34
0
 public void UsesStaticSerializerAndDeserializerMethodsAutomatically()
 {
     var key = new TangleKey("hello");
     Scheduler.WaitFor(Tangle.Set(key, new SpecialType(key, 4)));
     var result = Scheduler.WaitFor(Tangle.Get("hello"));
     Assert.AreEqual(4, result.Value);
 }
예제 #35
0
 public void NumericKeysWork()
 {
     var key = new TangleKey(1234);
     Scheduler.WaitFor(Tangle.Set(key, 1));
     Assert.AreEqual(1, Scheduler.WaitFor(Tangle.Get(key)));
 }
예제 #36
0
        public bool ReadKey(BTreeValue *pEntry, out TangleKey key)
        {
            ushort keyType = pEntry->KeyType;

            return(ReadKey(pEntry, keyType, out key));
        }
예제 #37
0
        public void SerializerAndDeserializerHaveAccessToKey()
        {
            var key = new TangleKey("hello");

            // This will fail because the specified keys don't match, and that lets us know
            //  that the serializer had access to the key. Kind of a hack.
            try {
                Scheduler.WaitFor(Tangle.Set("world", new SpecialType(key, 4)));
            } catch (FutureException fe) {
                Assert.IsInstanceOf<SerializerThrewException>(fe.InnerException);
                Assert.IsInstanceOf<InvalidDataException>(fe.InnerException.InnerException);
            }

            // As a side effect, this also tests the Tangle's ability to recover from
            //  a failed serialization. If an exception from the Serializer were to bubble
            //  up, the BTree would be left in an invalid state and this set would fail.
            Scheduler.WaitFor(Tangle.Set(key, new SpecialType(key, 4)));

            var result = Scheduler.WaitFor(Tangle.Get("hello"));
            Assert.IsTrue(key.Equals(result.Key));
        }
예제 #38
0
 public SpecialType(TangleKey key, UInt32 value)
 {
     Key   = key;
     Value = value;
 }
예제 #39
0
 public SpecialType(TangleKey key, UInt32 value)
 {
     Key = key;
     Value = value;
 }
예제 #40
0
        public void TestRepeatedGrowAndShrink()
        {
            var wasted1 = Tangle.WastedDataBytes;

            for (int i = 1; i < 50; i += 10) {
                for (int j = 0; j < 20; j++) {
                    var key = new TangleKey(String.Format("test{0}", j));
                    var text = new String((char)(j + 63), i);

                    Scheduler.WaitFor(Tangle.Set(key, text));

                    Assert.AreEqual(
                        text, Scheduler.WaitFor(Tangle.Get(key))
                    );
                }
            }

            var wasted2 = Tangle.WastedDataBytes;
            Assert.Greater(wasted2, wasted1);

            for (int j = 0; j < 20; j++) {
                var key = new TangleKey(String.Format("test{0}", j));
                var text = new String((char)(j + 63), 5);

                Scheduler.WaitFor(Tangle.Set(key, text));

                Assert.AreEqual(
                    text, Scheduler.WaitFor(Tangle.Get(key))
                );
            }

            var wasted3 = Tangle.WastedDataBytes;
            Assert.AreEqual(wasted3, wasted2);

            for (int j = 20; j < 40; j++) {
                var key = new TangleKey(String.Format("test{0}", j));
                var text = new String((char)(j + 63), 10);

                Scheduler.WaitFor(Tangle.Set(key, text));

                Assert.AreEqual(
                    text, Scheduler.WaitFor(Tangle.Get(key))
                );
            }

            // This will fail if the freelist is not being used
            Assert.Less(Tangle.WastedDataBytes, wasted3, "Freelist not functioning");
        }