diff --git a/BinaryTreeIndex.Tests/BinaryTreeIndex.Tests.csproj b/BinaryTreeIndex.Tests/BinaryTreeIndex.Tests.csproj new file mode 100644 index 0000000..2489620 --- /dev/null +++ b/BinaryTreeIndex.Tests/BinaryTreeIndex.Tests.csproj @@ -0,0 +1,99 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {BB2CA489-61D9-4033-B220-D55850BF5F9B} + Library + Properties + BinaryTreeIndex.Tests + BinaryTreeIndex.Tests + v4.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\NUnit\nunit.framework.dll + + + + + + + + + + + + + + + + {5A691EE2-96EE-4F5F-858E-6A17088CE7A1} + IGraphDB + + + {1FC72801-4046-4CC7-BF83-8082FFD593BC} + SonesGraphDB + + + {AB7C27CC-534F-472E-BA56-A1287973B7E2} + InMemoryNonRevisioned + + + {581F49A5-9768-4CB3-AF92-3A3FC2B1F63B} + Commons + + + {EA1F7F6C-C8C9-4529-998D-B86701FFA1DE} + ErrorHandling + + + {C6DDFD34-176E-48AC-998F-854F98CD28BB} + IPluginable + + + {A1BD782F-F3C4-4820-8B00-FDBDAADAE37D} + PropertyHyperGraph + + + {FCF3C622-5CF6-4C2A-B024-4046D6E4941C} + SonesIndices + + + {823E8AF4-CF92-4E74-8ABD-38693279EB1E} + ISonesIndex + + + {F49E824F-7917-44A2-A4B4-7167F61C2836} + BinaryTreeIndex + + + + + \ No newline at end of file diff --git a/BinaryTreeIndex.Tests/BinaryTreeIndexTests.cs b/BinaryTreeIndex.Tests/BinaryTreeIndexTests.cs new file mode 100644 index 0000000..675b275 --- /dev/null +++ b/BinaryTreeIndex.Tests/BinaryTreeIndexTests.cs @@ -0,0 +1,1105 @@ +/* +* sones GraphDB - Community Edition - http://www.sones.com +* Copyright (C) 2007-2011 sones GmbH +* +* This file is part of sones GraphDB Community Edition. +* +* sones GraphDB is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as published by +* the Free Software Foundation, version 3 of the License. +* +* sones GraphDB is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with sones GraphDB. If not, see . +* +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using NUnit.Framework; +using sones.GraphDB; +using sones.GraphDB.Manager; +using sones.GraphDB.Request; +using sones.GraphDB.TypeSystem; +using sones.GraphFS.Element.Vertex; +using sones.Library.Commons.Security; +using sones.Library.PropertyHyperGraph; +using sones.Plugins.Index.ErrorHandling; +using sones.Plugins.Index.Helper; + +namespace s1ck.GraphDB.Plugins.Index.BinaryTree.Tests +{ + [TestFixture] + public class BinaryTreeIndexTests + { + #region Tests + + #region KeyCount / ValueCount Tests + + /// + /// This test checks if the number of added keys is equal to key count. + /// + [TestCase] + public void KeyCountTest() + { + #region data + + var idx = new BinaryTreeIndex(); + + var kvp = new List>() + { + new KeyValuePair(1, 1), + new KeyValuePair(1, 2), + new KeyValuePair(2, 3), + new KeyValuePair(2, 4), + new KeyValuePair(2, 5), + }; + + idx.AddRange(kvp, IndexAddStrategy.MERGE); + + #endregion + + #region test + + Assert.That(idx.KeyCount(), Is.EqualTo(2)); + + #endregion + + } + + /// + /// This test checks if the number of added values is equal to value count. + /// + [TestCase] + public void ValueCountTest() + { + #region data + + var idx = new BinaryTreeIndex(); + + var kvp = new List>() + { + new KeyValuePair(1, 1), + new KeyValuePair(1, 2), + new KeyValuePair(2, 3), + new KeyValuePair(2, 4), + new KeyValuePair(2, 5), + }; + + idx.AddRange(kvp, IndexAddStrategy.MERGE); + + #endregion + + #region test + + Assert.That(idx.ValueCount(), Is.EqualTo(5)); + + #endregion + } + + #endregion + + #region Keys Tests + + /// + /// This test inserts a set of keys into the index and checks if they were stored correctly. + /// + [TestCase] + public virtual void Keys() + { + #region data + + var idx = new BinaryTreeIndex(); + + var n = 10; + var vertices = CreateKeyValuePairs(n); + + #endregion + + #region test + + idx.AddRange(vertices); + + var keys = idx.Keys(); + + Assert.That(keys.LongCount(), Is.EqualTo(n)); + + for (long i = 0; i < n; i++) + { + CollectionAssert.Contains(keys, i); + } + + #endregion + } + + #endregion + + #region Add Tests + + /// + /// This test adds a vertex to the index and checks if it was correctly added. + /// + [TestCase] + public virtual void Add_InsertVertex() + { + #region data + + var idx = new BinaryTreeIndex(); + + var vertexID = 1L; + var propertyID = 1L; + var propertyValue = 10; + // set propertyID for index + idx.Init(new List() { propertyID }); + + // create a vertex + var v = new InMemoryVertex(vertexID, + 1L, + 1L, + null, + null, + null, + "dummy", + DateTime.Now.Ticks, + DateTime.Now.Ticks, + new Dictionary() { { propertyID, propertyValue } }, // structured properties + null); + + #endregion + + #region test + + // add + idx.Add(v); + + Assert.AreEqual(1, idx.KeyCount()); + Assert.AreEqual(1, idx.ValueCount()); + + Assert.IsTrue(idx[propertyValue].Contains(vertexID)); + + #endregion + } + + /// + /// This test adds a vertex to the index which doesn't have the indexed property. + /// This causes no error, but the vertex won't be added to the index. + /// + [TestCase] + public virtual void Add_InsertVertex_Fails() + { + #region data + + var idx = new BinaryTreeIndex(); + + var vertexID = 1L; + var propertyID = 1L; + var fake_propertyID = 2L; + var propertyValue = 10; + // set propertyID for index + idx.Init(new List() { propertyID }); + + // create a vertex + var v = new InMemoryVertex(vertexID, + 1L, + 1L, + null, + null, + null, + "dummy", + DateTime.Now.Ticks, + DateTime.Now.Ticks, + new Dictionary() { { fake_propertyID, propertyValue } }, // structured properties + null); + + #endregion + + #region test + + // this won't add the vertex because it doesn't have the indexed property + idx.Add(v); + Assert.That(idx.KeyCount(), Is.EqualTo(0L), "vertex has been added by mistake"); + Assert.That(idx.ValueCount(), Is.EqualTo(0L), "vertex has been added by mistake"); + + #endregion + } + + /// + /// This tests adds an already existing key and an associated value to the index. + /// This should throw an IndexKeyExistsException. + /// + [TestCase] + public virtual void Add_InsertKeyValue_IndexAddStrategy_Unique() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 1; + var val_1 = 1; + + #endregion + + #region test + + idx.Add(key_1, val_1); + + // inserting existing key throws exception when strategy is unique + Assert.Throws(typeof(IndexKeyExistsException), () => + { + idx.Add(key_1, val_1, IndexAddStrategy.UNIQUE); + }); + + #endregion + } + + /// + /// This test adds an already existing key and an associated value to the index. + /// By using IndexAddStrategy.Merge two values should be associated to the key. + /// + [TestCase] + public virtual void Add_InsertKeyValue_IndexAddStrategy_Merge() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 1; + + var val_1 = 1; + var val_2 = 2; + + #endregion + + #region test + + // insert first key value + idx.Add(key_1, val_1, IndexAddStrategy.MERGE); + + // index must contain key and one value + Assert.IsTrue(idx[key_1].Contains(val_1)); + Assert.AreEqual(1, idx[key_1].Count()); + + // merge a second value with the currently stored one + idx.Add(key_1, val_2, IndexAddStrategy.MERGE); + + // index now contains two values for the key + Assert.IsTrue(idx[1].Contains(val_1)); + Assert.IsTrue(idx[1].Contains(val_2)); + Assert.AreEqual(2, idx[1].Count()); + + idx.Clear(); + + #endregion + } + + /// + /// This test adds an already existing key and an associated value to the index. + /// By using IndexAddStrategy.Replace the new value should be associated to the key. + /// + [TestCase] + public virtual void Add_InsertKeyValue_IndexAddStrategy_Replace() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 1; + var val_1 = 1; + var val_2 = 2; + + #endregion + + #region test + + // insert first key value + idx.Add(key_1, val_1, IndexAddStrategy.MERGE); + + // index must contain key and one value + Assert.IsTrue(idx[key_1].Contains(val_1)); + Assert.AreEqual(1, idx[key_1].Count()); + + // idx value count + Assert.AreEqual(1, idx.ValueCount()); + + // replace first value by the second + idx.Add(1, val_2, IndexAddStrategy.REPLACE); + + // index now contains the new value for the key + Assert.IsTrue(idx[key_1].Contains(val_2)); + Assert.AreEqual(1, idx[key_1].Count()); + + // idx value count + Assert.AreEqual(1, idx.ValueCount()); + + idx.Clear(); + + #endregion + } + + /// + /// This test inserts a null-key to the index and checks if an exception is thrown + /// or if is inserted correctly. An Exception will be thrown if the index doesn't support + /// null-keys. + /// + [TestCase] + public virtual void Add_InsertNull() + { + #region data + + var idx = new BinaryTreeIndex(); + + var val_1 = 0; + + #endregion + + #region Test + + if (idx.SupportsNullableKeys) + { + idx.Add(null, val_1); + Assert.That(idx.KeyCount(), Is.EqualTo(1)); + Assert.That(idx.ValueCount(), Is.EqualTo(1)); + } + else + { + Assert.Throws(typeof(NullKeysNotSupportedException), () => idx.Add(null, val_1)); + } + + #endregion + } + + /// + /// This test inserts a list of vertices into the index and checks if they have + /// been added correctly. + /// + [TestCase] + public virtual void AddRange_InsertVertices() + { + #region data + + var idx = new BinaryTreeIndex(); + + var n = 10; + var propertyID = 1L; + var vertices = CreateVertices(n, propertyID); + + idx.Init(new List() { propertyID }); + + #endregion + + #region Test + + idx.AddRange(vertices); + + // check counts + Assert.That(idx.KeyCount(), Is.EqualTo(n)); + Assert.That(idx.KeyCount(), Is.EqualTo(n)); + + // check propertyIDs + for (long vID = 0; vID < n; vID++) + { + Assert.IsTrue(idx.ContainsKey(vID)); + Assert.IsTrue(idx[vID].Contains(vID)); + Assert.That(idx[vID].LongCount(), Is.EqualTo(1L)); + } + + #endregion + } + + /// + /// This test insert a list of key-value-pairs into the index and checks if they + /// have been added correctly. + /// + [TestCase] + public virtual void AddRange_InsertKeyValuePairs() + { + #region data + + var idx = new BinaryTreeIndex(); + + var n = 10; + var vertices = CreateKeyValuePairs(n); + + #endregion + + #region test + + idx.AddRange(vertices); + + // check counts + Assert.That(idx.KeyCount(), Is.EqualTo(n)); + Assert.That(idx.KeyCount(), Is.EqualTo(n)); + + // check propertyIDs + for (long vID = 0; vID < n; vID++) + { + Assert.IsTrue(idx.ContainsKey(vID)); + Assert.IsTrue(idx[vID].Contains(vID)); + Assert.That(idx[vID].LongCount(), Is.EqualTo(1L)); + } + + #endregion + } + + #endregion + + #region Init Tests + + /// + /// This test inits an index with a list of propertyIDs to index. + /// Via reflection, the stored list will be checked against the defined list. + /// + [TestCase] + public virtual void Init_CheckPrivateMemberEquality() + { + #region data + + var idx = new BinaryTreeIndex(); + + #endregion + + #region + + // init the index with some propertyIDs + var definedPropertyIDs = new List() { 0L, 1L }; + idx.Init(definedPropertyIDs); + + // use some reflection action to get the private member of the index instance + var indexedPropertyIDs = (List)idx.GetType().GetField("_PropertyIDs", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(idx); + + CollectionAssert.AreEqual(definedPropertyIDs, indexedPropertyIDs, "indexed propertyIDs do not match"); + + #endregion + } + + #endregion + + #region TryGetValues Tests + + /// + /// This test checks if the TryGetValues method returns the correct values. + /// + [TestCase] + public virtual void TryGetValues_ExistingKey() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 10; + var key_2 = 11; + + var val_1 = 2; + var val_2 = 3; + var val_3 = 5; + + #endregion + + #region test + + idx.Add(key_1, val_1); + idx.Add(key_1, val_2, IndexAddStrategy.MERGE); + + idx.Add(key_2, val_3); + + Assert.AreEqual(2, idx.KeyCount(), "The number of keys is not correct."); + Assert.AreEqual(3, idx.ValueCount(), "The number of values is not correct."); + + // TryGetValues test + IEnumerable result; + Assert.IsTrue(idx.TryGetValues(key_1, out result)); + Assert.IsTrue(result.Contains(val_1)); + Assert.IsTrue(result.Contains(val_2)); + Assert.AreEqual(2, result.Count()); + + Assert.IsTrue(idx.TryGetValues(key_2, out result)); + Assert.IsTrue(result.Contains(val_3)); + Assert.AreEqual(1, result.Count()); + + #endregion + } + + /// + /// This test uses the TryGetValue Method to load a key, which doesn't exist + /// in the index. This should return false and the out param is null because + /// no extra object will be created in that case. + /// + [TestCase] + public virtual void TryGetValues_NonExistingKey() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 10; + var key_2 = 11; + var key_3 = 12; + + var val_1 = 2; + var val_2 = 3; + var val_3 = 5; + + #endregion + + #region test + + idx.Add(key_1, val_1); + idx.Add(key_1, val_2, IndexAddStrategy.MERGE); + + idx.Add(key_2, val_3); + + Assert.AreEqual(2, idx.KeyCount(), "The number of keys is not correct."); + Assert.AreEqual(3, idx.ValueCount(), "The number of values is not correct."); + + // TryGetValues with non existing key + IEnumerable result; + Assert.IsFalse(idx.TryGetValues(key_3, out result)); + Assert.IsNull(result); + + #endregion + } + + #endregion + + #region this[] Tests + + /// + /// This test checks the this[] call to an index using an existing key. + /// + [TestCase] + public virtual void this_ExistingKey() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 1; + var val_1 = 1; + + #endregion + + #region test + + idx.Add(key_1, val_1); + + Assert.IsNotNull(idx[key_1]); + CollectionAssert.Contains(idx[key_1], val_1); + Assert.AreEqual(1L, idx[key_1].LongCount()); + + #endregion + } + + /// + /// This test checks the this[] call to an index using an non existing key. + /// This should throw an IndexKeyNotFoundException. + /// + [TestCase] + public virtual void this_NonExistingKey_ThrowsException() + { + #region data + + var idx = new BinaryTreeIndex(); + var key_1 = 1; + + #endregion + + #region test + + Assert.Throws(typeof(IndexKeyNotFoundException), () => idx[key_1].LongCount()); + + #endregion + } + + #endregion + + #region ContainsKey Tests + + /// + /// This test inserts a key-value-pair and checks if the key exsists. + /// Should return true. + /// + [TestCase] + public virtual void ContainsKey_True() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 1; + var val_1 = 1; + + #endregion + + #region + + idx.Add(key_1, val_1); + + Assert.IsTrue(idx.ContainsKey(key_1)); + + #endregion + } + + /// + /// This test if a not-added key exsists. + /// Should return false + /// + [TestCase] + public virtual void ContainsKey_False() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 1; + + #endregion + + #region + + Assert.IsFalse(idx.ContainsKey(key_1)); + + #endregion + } + + #endregion + + #region Remove / TryRemoveValue Tests + + /// + /// This test adds a key-value-pair and removed the key. + /// Should return true. + /// + [TestCase] + public virtual void Remove_True() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 1L; + var val_1 = 1L; + + #endregion + + #region test + + idx.Add(key_1, val_1); + + Assert.AreEqual(1L, idx.KeyCount()); + Assert.AreEqual(1L, idx.ValueCount()); + + // remove the key + Assert.IsTrue(idx.Remove(key_1)); + // and check the counters + Assert.AreEqual(0L, idx.KeyCount()); + Assert.AreEqual(0L, idx.ValueCount()); + + #endregion + } + + /// + /// This tests adds some key-value-pairs and tries to + /// remove non existing keys from the index. This call + /// should return false. + /// + [TestCase] + public virtual void Remove_False() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 1L; + var key_2 = 2L; + var key_3 = 3L; + + var val_1 = 1L; + var val_2 = 2L; + + #endregion + + #region test + + idx.Add(key_1, val_1); + idx.Add(key_2, val_2); + + Assert.AreEqual(2L, idx.KeyCount()); + Assert.AreEqual(2L, idx.ValueCount()); + + // remove the not existing key 3 + Assert.IsFalse(idx.Remove(key_3)); + // and check the counters + Assert.AreEqual(2L, idx.KeyCount()); + Assert.AreEqual(2L, idx.ValueCount()); + + // remove existing key 1 + Assert.IsTrue(idx.Remove(key_1)); + // and check the counters + Assert.AreEqual(1L, idx.KeyCount()); + Assert.AreEqual(1L, idx.ValueCount()); + + // remove not existing key 1 + Assert.IsFalse(idx.Remove(key_1)); + // and check the counters + Assert.AreEqual(1L, idx.KeyCount()); + Assert.AreEqual(1L, idx.ValueCount()); + + #endregion + } + + /// + /// This test tries to remove a value associated with a key. + /// Both, key and value exist in the index, and the value is + /// associated with the key. + /// This should return true. + /// + [TestCase] + public virtual void TryRemoveValue_ExistingKey_ExistingValue() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 1; + var val_1 = 1; + var val_2 = 2; + + #endregion + + #region test + + idx.Add(key_1, val_1); + + // counter + Assert.That(idx.KeyCount(), Is.EqualTo(1)); + Assert.That(idx.ValueCount(), Is.EqualTo(1)); + + // try to remove existing value (only one value, this means the index has to be deleted too) + Assert.IsTrue(idx.TryRemoveValue(key_1, val_1)); + Assert.That(idx.KeyCount(), Is.EqualTo(0)); + Assert.That(idx.ValueCount(), Is.EqualTo(0)); + + // add two values for one key + idx.Add(key_1, val_1); + idx.Add(key_1, val_2, IndexAddStrategy.MERGE); + + Assert.That(idx.KeyCount(), Is.EqualTo(1)); + Assert.That(idx.ValueCount(), Is.EqualTo(2)); + + // remove one value + Assert.That(idx.TryRemoveValue(key_1, val_1), Is.True); + Assert.That(idx.KeyCount(), Is.EqualTo(1)); + Assert.That(idx.ValueCount(), Is.EqualTo(1)); + Assert.That(idx[key_1].Contains(val_2), Is.True); + Assert.That(idx[key_1].LongCount(), Is.EqualTo(1)); + + #endregion + } + + /// + /// This test tries to remove a value associated with a key. + /// The key is stored in the index but the value is not + /// associated with the key. + /// This should return false. + [TestCase] + public virtual void TryRemoveValue_ExistingKey_NonExistingValue() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 1; + + var val_1 = 1; + var val_2 = 2; + + #endregion + + #region test + + idx.Add(key_1, val_1); + + // counter + Assert.That(idx.KeyCount(), Is.EqualTo(1)); + Assert.That(idx.ValueCount(), Is.EqualTo(1)); + + // try to remove existing value (only one value, this means the index has to be deleted too) + Assert.IsFalse(idx.TryRemoveValue(key_1, val_2)); + Assert.That(idx.KeyCount(), Is.EqualTo(1)); + Assert.That(idx.ValueCount(), Is.EqualTo(1)); + + #endregion + } + + /// + /// This test tries to remove a value associated with a key. + /// Neither the key or the value are stored in the index. + /// This should return false. + /// + [TestCase] + public virtual void TryRemoveValue_NonExistingKey_NonExistingValue() + { + #region data + + var idx = new BinaryTreeIndex(); + + var key_1 = 1; + var key_2 = 2; + + var val_1 = 1; + var val_2 = 2; + + #endregion + + #region test + + idx.Add(key_1, val_1); + + // counter + Assert.That(idx.KeyCount(), Is.EqualTo(1)); + Assert.That(idx.ValueCount(), Is.EqualTo(1)); + + // try to remove existing value (only one value, this means the index has to be deleted too) + Assert.IsFalse(idx.TryRemoveValue(key_2, val_2)); + Assert.That(idx.KeyCount(), Is.EqualTo(1)); + Assert.That(idx.ValueCount(), Is.EqualTo(1)); + + #endregion + } + + /// + /// This test removes a collection of vertices from the index. + /// + [TestCase] + public virtual void RemoveRange_RemoveVertices() + { + #region data + + var n = 10; + var propertyID = 1L; + var idx = new BinaryTreeIndex(); + var vertices = CreateVertices(n, propertyID); + + idx.Init(new List() { propertyID }); + + #endregion + + #region test + + idx.AddRange(vertices); + + Assert.That(idx.KeyCount(), Is.EqualTo(n)); + Assert.That(idx.ValueCount(), Is.EqualTo(n)); + + idx.RemoveRange(vertices); + + Assert.That(idx.KeyCount(), Is.EqualTo(0)); + Assert.That(idx.ValueCount(), Is.EqualTo(0)); + + #endregion + + } + + /// + /// This tests remove a collection of keys from the index. + /// + [TestCase] + public virtual void RemoveRange_RemoveKeys() + { + #region data + + var n = 10; + var idx = new BinaryTreeIndex(); + var vertices = CreateKeyValuePairs(n); + + #endregion + + #region test + + idx.AddRange(vertices); + + Assert.That(idx.KeyCount(), Is.EqualTo(n)); + Assert.That(idx.ValueCount(), Is.EqualTo(n)); + + idx.RemoveRange(vertices.Select(kvp => kvp.Key)); + + Assert.That(idx.KeyCount(), Is.EqualTo(0)); + Assert.That(idx.ValueCount(), Is.EqualTo(0)); + + #endregion + } + + #endregion + + #region Clear Tests + + /// + /// This test inserts some data into the index and then + /// clears it. All data has to be removed after that call. + /// + [TestCase] + public virtual void Clear_RemoveAllKeys() + { + #region data + + var n = 10; + var idx = new BinaryTreeIndex(); + var vertices = CreateKeyValuePairs(n); + + #endregion + + #region test + + idx.AddRange(vertices); + + Assert.That(idx.KeyCount(), Is.EqualTo(n)); + Assert.That(idx.ValueCount(), Is.EqualTo(n)); + + idx.Clear(); + + Assert.That(idx.KeyCount(), Is.EqualTo(0)); + Assert.That(idx.ValueCount(), Is.EqualTo(0)); + + #endregion + } + + #endregion + + #region InitializePlugin Tests + + /// + /// This tests checks if the propertyID of an indexed is correctly set + /// after initializing the plugin. + /// + [TestCase] + public void InitializePlugin_CheckPropertyIDs() + { + #region data + + // create db + var graphDB = new SonesGraphDB(); + var transactionToken = 0L; + var securityToken = new SecurityToken(); + + // create vertex type with attribute + var vertexType = graphDB.CreateVertexType(securityToken, + transactionToken, + new RequestCreateVertexType( + new VertexTypePredefinition("dummy") + .AddProperty(new PropertyPredefinition("age", "Int32"))), + (stats, type) => type); + + // create persistent index on attribute + var indexDef = graphDB.CreateIndex(securityToken, + transactionToken, + new RequestCreateIndex(new IndexPredefinition("myindex", "dummy").AddProperty("age").SetIndexType("binarytree")), + (stats, index) => index); + + #endregion + + #region test + + var metaManager = GetMetaManager(graphDB); + var sonesIdx = metaManager.IndexManager.GetIndex("myindex", securityToken, transactionToken); + + // propertyID stored at the index + var indexPropertyIDs = (List)new BinaryTreeIndex().GetType().GetField("_PropertyIDs", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(sonesIdx); + + // propertyID stored at the vertextype + var propID = vertexType.GetPropertyDefinition("age").ID; + + Assert.IsTrue(indexPropertyIDs.Contains(propID), "indexed propertyID is not the same as propertyID at vertex type"); + + #endregion + + #region Cleanup + + graphDB.Shutdown(securityToken); + + #endregion + } + + #endregion + + #endregion + + #region Private Helper + + /// + /// Creates a list of vertices. VertexID are in ascending order beginning at 0. + /// The value of the defined property is equal to the vertexID. + /// + /// Define how many vertices shall be created. + /// The property to set + /// A list of vertices + private IList CreateVertices(int myNumberOfVertices, Int64 myPropertyID) + { + var list = new List(myNumberOfVertices); + + for (long i = 0; i < myNumberOfVertices; i++) + { + list.Add(new InMemoryVertex(i, + 1L, + 1L, + null, + null, + null, + "dummy", + DateTime.Now.Ticks, + DateTime.Now.Ticks, + new Dictionary() { { myPropertyID, i } }, // structured properties + null)); + } + + return list; + } + + /// + /// Creates a list of key-value-pairs of type long, long. Key and value are equal. + /// + /// Define how many key-value-pairs shall be created + /// A list of key-value-pairs + private IEnumerable> CreateKeyValuePairs(int myNumberOfPairs) + { + var list = new List>(myNumberOfPairs); + + for (long i = 0; i < myNumberOfPairs; i++) + { + list.Add(new KeyValuePair(i, i)); + } + + return list; + } + + /// + /// Uses reflection to get the RequestManager + /// + /// A GraphDB instance + /// RequestManager + protected SimpleRequestManager GetRequestManager(IGraphDB myGraphDB) + { + //gets the private IRequestManager of the _graphDBInstance + return (SimpleRequestManager)typeof(sones.GraphDB.SonesGraphDB).GetField("_requestManager", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(myGraphDB); + } + + /// + /// Uses reflection to the the MetaManager + /// + /// A GraphDB instance + /// MetaManager + protected IMetaManager GetMetaManager(IGraphDB myGraphDB) + { + //gets the private IMetaManager of the IRequestManagerInstance + return (IMetaManager)typeof(SimpleRequestManager).GetField("_metaManager", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(GetRequestManager(myGraphDB)); + } + + #endregion + + } +} diff --git a/BinaryTreeIndex.Tests/Properties/AssemblyInfo.cs b/BinaryTreeIndex.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..233e77e --- /dev/null +++ b/BinaryTreeIndex.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BinaryTreeIndex.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("BinaryTreeIndex.Tests")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ccc708dd-ff14-4802-aab6-7d15df7b0b92")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/BinaryTreeIndex.Tests/bin/Debug/BinaryStreamStructure.dll b/BinaryTreeIndex.Tests/bin/Debug/BinaryStreamStructure.dll new file mode 100644 index 0000000..4a7fadc Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/BinaryStreamStructure.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/BinaryStreamStructure.pdb b/BinaryTreeIndex.Tests/bin/Debug/BinaryStreamStructure.pdb new file mode 100644 index 0000000..e9ac709 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/BinaryStreamStructure.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.Tests.dll b/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.Tests.dll new file mode 100644 index 0000000..5b28a2a Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.Tests.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.Tests.dll.VisualState.xml b/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.Tests.dll.VisualState.xml new file mode 100644 index 0000000..f848c56 --- /dev/null +++ b/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.Tests.dll.VisualState.xml @@ -0,0 +1,16 @@ + + + [0-1055]S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\BinaryTreeIndex.Tests.dll + [0-1039]s1ck.GraphDB.Plugins.Index.BinaryTree.Tests.BinaryTreeIndexTests.Remove_False + false + + + + + + + + + + + \ No newline at end of file diff --git a/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.Tests.pdb b/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.Tests.pdb new file mode 100644 index 0000000..c5e899e Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.Tests.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.dll b/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.dll new file mode 100644 index 0000000..726780b Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.pdb b/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.pdb new file mode 100644 index 0000000..3be4ed9 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/BinaryTreeIndex.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/CollectionWrapper.dll b/BinaryTreeIndex.Tests/bin/Debug/CollectionWrapper.dll new file mode 100644 index 0000000..382730b Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/CollectionWrapper.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/CollectionWrapper.pdb b/BinaryTreeIndex.Tests/bin/Debug/CollectionWrapper.pdb new file mode 100644 index 0000000..5734718 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/CollectionWrapper.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/Commons.dll b/BinaryTreeIndex.Tests/bin/Debug/Commons.dll new file mode 100644 index 0000000..e135b71 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/Commons.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/Commons.pdb b/BinaryTreeIndex.Tests/bin/Debug/Commons.pdb new file mode 100644 index 0000000..311013e Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/Commons.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/ErrorHandling.dll b/BinaryTreeIndex.Tests/bin/Debug/ErrorHandling.dll new file mode 100644 index 0000000..d7b9a7a Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/ErrorHandling.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/ErrorHandling.pdb b/BinaryTreeIndex.Tests/bin/Debug/ErrorHandling.pdb new file mode 100644 index 0000000..d7781ef Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/ErrorHandling.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/IGraphDB.dll b/BinaryTreeIndex.Tests/bin/Debug/IGraphDB.dll new file mode 100644 index 0000000..1cfa73c Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/IGraphDB.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/IGraphDB.pdb b/BinaryTreeIndex.Tests/bin/Debug/IGraphDB.pdb new file mode 100644 index 0000000..af5070b Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/IGraphDB.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/IGraphDBExtensions.dll b/BinaryTreeIndex.Tests/bin/Debug/IGraphDBExtensions.dll new file mode 100644 index 0000000..0a1e646 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/IGraphDBExtensions.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/IGraphDBExtensions.pdb b/BinaryTreeIndex.Tests/bin/Debug/IGraphDBExtensions.pdb new file mode 100644 index 0000000..88bbb33 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/IGraphDBExtensions.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/IGraphFS.dll b/BinaryTreeIndex.Tests/bin/Debug/IGraphFS.dll new file mode 100644 index 0000000..dc080a5 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/IGraphFS.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/IGraphFS.pdb b/BinaryTreeIndex.Tests/bin/Debug/IGraphFS.pdb new file mode 100644 index 0000000..b209410 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/IGraphFS.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/IPluginable.dll b/BinaryTreeIndex.Tests/bin/Debug/IPluginable.dll new file mode 100644 index 0000000..3296bff Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/IPluginable.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/IPluginable.pdb b/BinaryTreeIndex.Tests/bin/Debug/IPluginable.pdb new file mode 100644 index 0000000..1e9fe80 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/IPluginable.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/ISonesIndex.dll b/BinaryTreeIndex.Tests/bin/Debug/ISonesIndex.dll new file mode 100644 index 0000000..53ec1c3 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/ISonesIndex.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/ISonesIndex.pdb b/BinaryTreeIndex.Tests/bin/Debug/ISonesIndex.pdb new file mode 100644 index 0000000..380d2e0 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/ISonesIndex.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/InMemoryNonRevisioned.dll b/BinaryTreeIndex.Tests/bin/Debug/InMemoryNonRevisioned.dll new file mode 100644 index 0000000..56b0d82 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/InMemoryNonRevisioned.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/InMemoryNonRevisioned.pdb b/BinaryTreeIndex.Tests/bin/Debug/InMemoryNonRevisioned.pdb new file mode 100644 index 0000000..2a3f158 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/InMemoryNonRevisioned.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/LanguageExtensions.dll b/BinaryTreeIndex.Tests/bin/Debug/LanguageExtensions.dll new file mode 100644 index 0000000..fa3c551 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/LanguageExtensions.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/LanguageExtensions.pdb b/BinaryTreeIndex.Tests/bin/Debug/LanguageExtensions.pdb new file mode 100644 index 0000000..bfcffc0 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/LanguageExtensions.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/NewFastSerializer.dll b/BinaryTreeIndex.Tests/bin/Debug/NewFastSerializer.dll new file mode 100644 index 0000000..ceb76c1 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/NewFastSerializer.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/NewFastSerializer.pdb b/BinaryTreeIndex.Tests/bin/Debug/NewFastSerializer.pdb new file mode 100644 index 0000000..81da583 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/NewFastSerializer.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/PluginDefinition.dll b/BinaryTreeIndex.Tests/bin/Debug/PluginDefinition.dll new file mode 100644 index 0000000..9de7410 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/PluginDefinition.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/PluginDefinition.pdb b/BinaryTreeIndex.Tests/bin/Debug/PluginDefinition.pdb new file mode 100644 index 0000000..33e2bfa Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/PluginDefinition.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/PropertyHyperGraph.dll b/BinaryTreeIndex.Tests/bin/Debug/PropertyHyperGraph.dll new file mode 100644 index 0000000..391e4ce Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/PropertyHyperGraph.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/PropertyHyperGraph.pdb b/BinaryTreeIndex.Tests/bin/Debug/PropertyHyperGraph.pdb new file mode 100644 index 0000000..d4750a7 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/PropertyHyperGraph.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/Settings.dll b/BinaryTreeIndex.Tests/bin/Debug/Settings.dll new file mode 100644 index 0000000..d0c4060 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/Settings.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/Settings.pdb b/BinaryTreeIndex.Tests/bin/Debug/Settings.pdb new file mode 100644 index 0000000..ddee8d0 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/Settings.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/SonesGraphDB.dll b/BinaryTreeIndex.Tests/bin/Debug/SonesGraphDB.dll new file mode 100644 index 0000000..c2d8992 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/SonesGraphDB.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/SonesGraphDB.pdb b/BinaryTreeIndex.Tests/bin/Debug/SonesGraphDB.pdb new file mode 100644 index 0000000..64c478e Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/SonesGraphDB.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/SonesIndices.dll b/BinaryTreeIndex.Tests/bin/Debug/SonesIndices.dll new file mode 100644 index 0000000..52098e8 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/SonesIndices.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/SonesIndices.pdb b/BinaryTreeIndex.Tests/bin/Debug/SonesIndices.pdb new file mode 100644 index 0000000..f370e8b Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/SonesIndices.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/TestResult.xml b/BinaryTreeIndex.Tests/bin/Debug/TestResult.xml new file mode 100644 index 0000000..c5f9060 --- /dev/null +++ b/BinaryTreeIndex.Tests/bin/Debug/TestResult.xml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BinaryTreeIndex.Tests/bin/Debug/UserdefinedDataType.dll b/BinaryTreeIndex.Tests/bin/Debug/UserdefinedDataType.dll new file mode 100644 index 0000000..8891b6d Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/UserdefinedDataType.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/UserdefinedDataType.pdb b/BinaryTreeIndex.Tests/bin/Debug/UserdefinedDataType.pdb new file mode 100644 index 0000000..99ce096 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/UserdefinedDataType.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/VersionedPluginManager.dll b/BinaryTreeIndex.Tests/bin/Debug/VersionedPluginManager.dll new file mode 100644 index 0000000..da7e8bf Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/VersionedPluginManager.dll differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/VersionedPluginManager.pdb b/BinaryTreeIndex.Tests/bin/Debug/VersionedPluginManager.pdb new file mode 100644 index 0000000..569b3ea Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/VersionedPluginManager.pdb differ diff --git a/BinaryTreeIndex.Tests/bin/Debug/nunit.framework.dll b/BinaryTreeIndex.Tests/bin/Debug/nunit.framework.dll new file mode 100644 index 0000000..6856e51 Binary files /dev/null and b/BinaryTreeIndex.Tests/bin/Debug/nunit.framework.dll differ diff --git a/BinaryTreeIndex.Tests/obj/Debug/BinaryTreeIndex.Tests.csproj.FileListAbsolute.txt b/BinaryTreeIndex.Tests/obj/Debug/BinaryTreeIndex.Tests.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..9ca440b --- /dev/null +++ b/BinaryTreeIndex.Tests/obj/Debug/BinaryTreeIndex.Tests.csproj.FileListAbsolute.txt @@ -0,0 +1,46 @@ +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\BinaryTreeIndex.Tests.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\BinaryTreeIndex.Tests.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\BinaryTreeIndex.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\Commons.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\ErrorHandling.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\IGraphDB.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\InMemoryNonRevisioned.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\IPluginable.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\ISonesIndex.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\nunit.framework.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\PropertyHyperGraph.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\SonesGraphDB.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\SonesIndices.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\CollectionWrapper.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\Settings.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\VersionedPluginManager.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\IGraphFS.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\PluginDefinition.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\UserdefinedDataType.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\LanguageExtensions.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\IGraphDBExtensions.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\BinaryStreamStructure.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\NewFastSerializer.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\IGraphDB.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\SonesGraphDB.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\InMemoryNonRevisioned.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\Commons.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\ErrorHandling.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\IPluginable.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\PropertyHyperGraph.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\SonesIndices.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\ISonesIndex.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\BinaryTreeIndex.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\CollectionWrapper.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\Settings.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\VersionedPluginManager.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\IGraphFS.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\PluginDefinition.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\UserdefinedDataType.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\LanguageExtensions.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\IGraphDBExtensions.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\BinaryStreamStructure.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\bin\Debug\NewFastSerializer.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\obj\Debug\ResolveAssemblyReference.cache +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\obj\Debug\BinaryTreeIndex.Tests.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex.Tests\obj\Debug\BinaryTreeIndex.Tests.pdb diff --git a/BinaryTreeIndex.Tests/obj/Debug/BinaryTreeIndex.Tests.dll b/BinaryTreeIndex.Tests/obj/Debug/BinaryTreeIndex.Tests.dll new file mode 100644 index 0000000..5b28a2a Binary files /dev/null and b/BinaryTreeIndex.Tests/obj/Debug/BinaryTreeIndex.Tests.dll differ diff --git a/BinaryTreeIndex.Tests/obj/Debug/BinaryTreeIndex.Tests.pdb b/BinaryTreeIndex.Tests/obj/Debug/BinaryTreeIndex.Tests.pdb new file mode 100644 index 0000000..c5e899e Binary files /dev/null and b/BinaryTreeIndex.Tests/obj/Debug/BinaryTreeIndex.Tests.pdb differ diff --git a/BinaryTreeIndex.Tests/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/BinaryTreeIndex.Tests/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100644 index 0000000..44a87cd Binary files /dev/null and b/BinaryTreeIndex.Tests/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/BinaryTreeIndex.Tests/obj/Debug/ResolveAssemblyReference.cache b/BinaryTreeIndex.Tests/obj/Debug/ResolveAssemblyReference.cache new file mode 100644 index 0000000..73ba9d4 Binary files /dev/null and b/BinaryTreeIndex.Tests/obj/Debug/ResolveAssemblyReference.cache differ diff --git a/BinaryTreeIndex.sln b/BinaryTreeIndex.sln new file mode 100644 index 0000000..c98fa14 --- /dev/null +++ b/BinaryTreeIndex.sln @@ -0,0 +1,93 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BinaryTreeIndex", "BinaryTreeIndex\BinaryTreeIndex.csproj", "{F49E824F-7917-44A2-A4B4-7167F61C2836}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dependencies", "Dependencies", "{9485A936-E4F3-472A-9959-962AB1B08E93}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Commons", "..\CommunityEdition\Library\Internal\Commons\Commons.csproj", "{581F49A5-9768-4CB3-AF92-3A3FC2B1F63B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ErrorHandling", "..\CommunityEdition\Library\Internal\ErrorHandling\ErrorHandling.csproj", "{EA1F7F6C-C8C9-4529-998D-B86701FFA1DE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IGraphDB", "..\CommunityEdition\GraphDB\IGraphDB\IGraphDB.csproj", "{5A691EE2-96EE-4F5F-858E-6A17088CE7A1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InMemoryNonRevisioned", "..\CommunityEdition\GraphFS\Implementations\InMemoryNonRevisioned\InMemoryNonRevisioned.csproj", "{AB7C27CC-534F-472E-BA56-A1287973B7E2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IPluginable", "..\CommunityEdition\Library\Internal\IPluginable\IPluginable.csproj", "{C6DDFD34-176E-48AC-998F-854F98CD28BB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ISonesIndex", "..\CommunityEdition\Plugins\Index\ISonesIndex\ISonesIndex.csproj", "{823E8AF4-CF92-4E74-8ABD-38693279EB1E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PropertyHyperGraph", "..\CommunityEdition\Library\Internal\PropertyHyperGraph\PropertyHyperGraph.csproj", "{A1BD782F-F3C4-4820-8B00-FDBDAADAE37D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SonesGraphDB", "..\CommunityEdition\GraphDB\Implementations\SonesGraphDB\SonesGraphDB.csproj", "{1FC72801-4046-4CC7-BF83-8082FFD593BC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SonesIndices", "..\CommunityEdition\Plugins\Index\Indices\SonesIndices\SonesIndices.csproj", "{FCF3C622-5CF6-4C2A-B024-4046D6E4941C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BinaryTreeIndex.Tests", "BinaryTreeIndex.Tests\BinaryTreeIndex.Tests.csproj", "{BB2CA489-61D9-4033-B220-D55850BF5F9B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F49E824F-7917-44A2-A4B4-7167F61C2836}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F49E824F-7917-44A2-A4B4-7167F61C2836}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F49E824F-7917-44A2-A4B4-7167F61C2836}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F49E824F-7917-44A2-A4B4-7167F61C2836}.Release|Any CPU.Build.0 = Release|Any CPU + {581F49A5-9768-4CB3-AF92-3A3FC2B1F63B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {581F49A5-9768-4CB3-AF92-3A3FC2B1F63B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {581F49A5-9768-4CB3-AF92-3A3FC2B1F63B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {581F49A5-9768-4CB3-AF92-3A3FC2B1F63B}.Release|Any CPU.Build.0 = Release|Any CPU + {EA1F7F6C-C8C9-4529-998D-B86701FFA1DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EA1F7F6C-C8C9-4529-998D-B86701FFA1DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EA1F7F6C-C8C9-4529-998D-B86701FFA1DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EA1F7F6C-C8C9-4529-998D-B86701FFA1DE}.Release|Any CPU.Build.0 = Release|Any CPU + {5A691EE2-96EE-4F5F-858E-6A17088CE7A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A691EE2-96EE-4F5F-858E-6A17088CE7A1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A691EE2-96EE-4F5F-858E-6A17088CE7A1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A691EE2-96EE-4F5F-858E-6A17088CE7A1}.Release|Any CPU.Build.0 = Release|Any CPU + {AB7C27CC-534F-472E-BA56-A1287973B7E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AB7C27CC-534F-472E-BA56-A1287973B7E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AB7C27CC-534F-472E-BA56-A1287973B7E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AB7C27CC-534F-472E-BA56-A1287973B7E2}.Release|Any CPU.Build.0 = Release|Any CPU + {C6DDFD34-176E-48AC-998F-854F98CD28BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6DDFD34-176E-48AC-998F-854F98CD28BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6DDFD34-176E-48AC-998F-854F98CD28BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6DDFD34-176E-48AC-998F-854F98CD28BB}.Release|Any CPU.Build.0 = Release|Any CPU + {823E8AF4-CF92-4E74-8ABD-38693279EB1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {823E8AF4-CF92-4E74-8ABD-38693279EB1E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {823E8AF4-CF92-4E74-8ABD-38693279EB1E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {823E8AF4-CF92-4E74-8ABD-38693279EB1E}.Release|Any CPU.Build.0 = Release|Any CPU + {A1BD782F-F3C4-4820-8B00-FDBDAADAE37D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1BD782F-F3C4-4820-8B00-FDBDAADAE37D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1BD782F-F3C4-4820-8B00-FDBDAADAE37D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1BD782F-F3C4-4820-8B00-FDBDAADAE37D}.Release|Any CPU.Build.0 = Release|Any CPU + {1FC72801-4046-4CC7-BF83-8082FFD593BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1FC72801-4046-4CC7-BF83-8082FFD593BC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1FC72801-4046-4CC7-BF83-8082FFD593BC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1FC72801-4046-4CC7-BF83-8082FFD593BC}.Release|Any CPU.Build.0 = Release|Any CPU + {FCF3C622-5CF6-4C2A-B024-4046D6E4941C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FCF3C622-5CF6-4C2A-B024-4046D6E4941C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FCF3C622-5CF6-4C2A-B024-4046D6E4941C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FCF3C622-5CF6-4C2A-B024-4046D6E4941C}.Release|Any CPU.Build.0 = Release|Any CPU + {BB2CA489-61D9-4033-B220-D55850BF5F9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB2CA489-61D9-4033-B220-D55850BF5F9B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB2CA489-61D9-4033-B220-D55850BF5F9B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB2CA489-61D9-4033-B220-D55850BF5F9B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {581F49A5-9768-4CB3-AF92-3A3FC2B1F63B} = {9485A936-E4F3-472A-9959-962AB1B08E93} + {EA1F7F6C-C8C9-4529-998D-B86701FFA1DE} = {9485A936-E4F3-472A-9959-962AB1B08E93} + {5A691EE2-96EE-4F5F-858E-6A17088CE7A1} = {9485A936-E4F3-472A-9959-962AB1B08E93} + {AB7C27CC-534F-472E-BA56-A1287973B7E2} = {9485A936-E4F3-472A-9959-962AB1B08E93} + {C6DDFD34-176E-48AC-998F-854F98CD28BB} = {9485A936-E4F3-472A-9959-962AB1B08E93} + {823E8AF4-CF92-4E74-8ABD-38693279EB1E} = {9485A936-E4F3-472A-9959-962AB1B08E93} + {A1BD782F-F3C4-4820-8B00-FDBDAADAE37D} = {9485A936-E4F3-472A-9959-962AB1B08E93} + {1FC72801-4046-4CC7-BF83-8082FFD593BC} = {9485A936-E4F3-472A-9959-962AB1B08E93} + {FCF3C622-5CF6-4C2A-B024-4046D6E4941C} = {9485A936-E4F3-472A-9959-962AB1B08E93} + EndGlobalSection +EndGlobal diff --git a/BinaryTreeIndex.suo b/BinaryTreeIndex.suo new file mode 100644 index 0000000..f7a3e86 Binary files /dev/null and b/BinaryTreeIndex.suo differ diff --git a/BinaryTreeIndex/BinaryTreeIndex.cs b/BinaryTreeIndex/BinaryTreeIndex.cs new file mode 100644 index 0000000..adb2df0 --- /dev/null +++ b/BinaryTreeIndex/BinaryTreeIndex.cs @@ -0,0 +1,666 @@ +/* +* sones GraphDB - Community Edition - http://www.sones.com +* Copyright (C) 2007-2011 sones GmbH +* +* This file is part of sones GraphDB Community Edition. +* +* sones GraphDB is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as published by +* the Free Software Foundation, version 3 of the License. +* +* sones GraphDB is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with sones GraphDB. If not, see . +* +*/ + +using System; +using System.Linq; +using System.Collections.Generic; +using sones.Library.VersionedPluginManager; +using sones.Plugins.Index.Abstract; +using sones.Plugins.Index.ErrorHandling; +using sones.Plugins.Index.Helper; + +namespace s1ck.GraphDB.Plugins.Index.BinaryTree +{ + /// + /// This class represents a sample index for the sones GraphDB. + /// + /// It is part of the tutorial on "Custom Indices" which can be + /// found here: + /// + /// http://developers.sones.de/wiki/doku.php?id=documentation:plugins:database:indices + /// + /// The implementation is a binary search tree as it is described here: + /// + /// http://en.wikipedia.org/wiki/Binary_tree + /// + /// The index can be used as 1:1 or 1:n mapping between keys + /// and associated values. It is not designed for production use, + /// there is no concerning about parallel access or persistence. + /// + /// Feel free to use this index as a starting point for own + /// implementations. + /// + /// Author: Martin "s1ck" Junghanns (martin.junghanns@sones.com) + /// + public class BinaryTreeIndex : ASonesIndex, IPluginable + { + #region Inner class BinaryTreeNode + + /// + /// This inner class represents a node in the binary tree. + /// Each node has a left and a right child node, a search key + /// and an associated value. + /// + /// Node: + /// Key ---> Set of values + /// / \ + /// / \ + /// Left Node Right Node + /// + class BinaryTreeNode + { + /// + /// Refers to the left child node + /// + public BinaryTreeNode Left; + /// + /// Refers to the right child node + /// + public BinaryTreeNode Right; + /// + /// The indexed search key for that node + /// + public IComparable Key; + /// + /// The associated values for the search key + /// + public HashSet Values; + /// + /// Creates a new instance of a tree node + /// + /// Search key + /// Associated values + public BinaryTreeNode(IComparable myKey, HashSet myValues) + { + Key = myKey; + Values = myValues; + Left = null; + Right = null; + } + } + + #endregion + + #region Private Members + + /// + /// Reference to the root node + /// + private BinaryTreeNode _Root; + /// + /// Number of keys stored in the tree + /// + private Int64 _KeyCount; + /// + /// Number of values stored in the tree + /// + private Int64 _ValueCount; + + #endregion + + #region Constructors + + /// + /// Empty constructor. This one is important for the sones PluginManager. + /// + public BinaryTreeIndex() + { + _KeyCount = 0L; + _ValueCount = 0L; + } + + /// + /// Initializes the binary tree index and assigns + /// a list of propertyIDs to the internal member. + /// + /// A list of indexed propertyIDs + public BinaryTreeIndex(IList myPropertyIDs) + : this() + { + _PropertyIDs = myPropertyIDs; + } + + #endregion + + #region IPluginable Members + + /// + /// Name of the plugin + /// + public string PluginName + { + get { return "sones.binarytreeindex"; } + } + + /// + /// Short name of the plugin + /// + public string PluginShortName + { + get { return "sones.bintreeidx"; } + } + + /// + /// Returns plugin parameters which can be set for this plugin. + /// + public PluginParameters SetableParameters + { + get + { + return new PluginParameters + { + }; + } + } + + /// + /// This method is called by the plugin manager when the plugin is loaded. + /// + /// It loads the indexed propertyIDs out of the parameter dictionary and + /// initializes the index with these propertyIDs + /// + /// + /// + /// An instance of the binary tree index + public IPluginable InitializePlugin(string UniqueString, Dictionary myParameters = null) + { + if (myParameters != null && myParameters.ContainsKey(IndexConstants.PROPERTY_IDS_OPTIONS_KEY)) + { + return new BinaryTreeIndex((IList)myParameters[IndexConstants.PROPERTY_IDS_OPTIONS_KEY]); + } + else + { + throw new ArgumentException("{0} were not set for initializing binary tree index", + IndexConstants.PROPERTY_IDS_OPTIONS_KEY); + } + } + + /// + /// Releases all resources which are hold by the index. + /// + public void Dispose() + { + + } + + #endregion + + #region ISonesIndex Members + + /// + /// The name of the index as it is used by the GraphQL (camel case). + /// + public override string IndexName + { + get { return "binarytree"; } + } + + /// + /// Returns the number of keys stored in the index. + /// + /// Number of stored keys + public override long KeyCount() + { + return _KeyCount; + } + + /// + /// Returns the number of values stored in the index. + /// + /// Number of stored values + public override long ValueCount() + { + return _ValueCount; + } + + /// + /// Returns sorted keys stored in the tree. + /// + /// An ordered list of index keys + public override IEnumerable Keys() + { + var result = new List(); + + if (_Root != null) + { + TraverseInOrder(_Root, ref result); + } + + return result; + } + + /// + /// Returns the type of the indexed keys. + /// + /// Note: If the index is empty the typeof(IComparable) will be returned. + /// + /// The type of the indexed keys or typeof(IComparable) if the index is empty. + public override Type GetKeyType() + { + return (_Root != null) ? _Root.Values.First().GetType() : typeof(IComparable); + } + + /// + /// Adds a search key and its associated value to the index. + /// + /// If IndexAddStrategy is REPLACE, an existing values associated with the key will be replaced by the new value. + /// If IndexAddStrategy is MERGE, the new value will be added to the existing set. + /// If IndexAddStrategy is UNIQUE, an exception will be thrown if the key already exists. + /// + /// Search key + /// Associated value + /// Define what happens, if the key already exists. + public override void Add(IComparable myKey, long myVertexID, + IndexAddStrategy myIndexAddStrategy = IndexAddStrategy.MERGE) + { + if (myKey == null) // uh, tree does not support null keys + { + throw new NullKeysNotSupportedException("binarytree index does not support null as key"); + } + + if (_Root == null) // nothing inserted yet -> create a new root + { + _Root = new BinaryTreeNode(myKey, new HashSet() { myVertexID }); + _KeyCount++; + _ValueCount++; + } + else + { + // insert into index + Add(_Root, myKey, myVertexID, myIndexAddStrategy); + } + } + + /// + /// Writes the associated value to the out param if the key exists. + /// + /// Search key + /// Stores the values (if any exist) + /// True, if the key has been found. + public override bool TryGetValues(IComparable myKey, out IEnumerable myVertexIDs) + { + BinaryTreeNode res; + if ((res = Find(_Root, myKey)) != null) + { + myVertexIDs = res.Values; + return true; + } + else + { + myVertexIDs = null; + return false; + } + } + + /// + /// Returns the values associated with the given key or throws + /// an Exception if the key does not exist. + /// + /// Search key + /// The associated values + public override IEnumerable this[IComparable myKey] + { + get + { + BinaryTreeNode res; + if ((res = Find(_Root, myKey)) != null) + { + return res.Values; + } + else + { + throw new IndexKeyNotFoundException( + String.Format("index key {0} was not found in binary tree", myKey)); + } + } + } + + /// + /// Checks if a given key exists in the index. + /// + /// Search key + /// True, if the key exists in the index. + public override bool ContainsKey(IComparable myKey) + { + if (myKey == null) + { + throw new NullKeysNotSupportedException("binarytree index does not support null as key"); + } + + return Find(_Root, myKey) != null; + } + + /// + /// Removes the given key and all associated values from the index. + /// + /// Search key + /// True, if the key has been found and removed + public override bool Remove(IComparable myKey) + { + if (myKey == null) + { + throw new NullKeysNotSupportedException("binarytree index does not support null as key"); + } + bool removed = false; + + _Root = Remove(_Root, myKey, ref removed); + + return removed; + } + + /// + /// Removes multiple keys from the index + /// + /// search keys to remove + public override void RemoveRange(IEnumerable myKeys) + { + foreach (var key in myKeys) + { + Remove(key); + } + } + + /// + /// Checks if a given value is associated with a given key and + /// if yes, the key will be deleted from the index. + /// + /// TODO: this method checks first if key and value exists + /// and then removes it. maybe this can be done in one step by + /// duplicating the remove method. + /// + /// search key + /// associated value + /// True, if key and value were deleted from the index + public override bool TryRemoveValue(IComparable myKey, long myValue) + { + if (myKey == null) + { + throw new NullKeysNotSupportedException("binarytree index does not support null as key"); + } + + BinaryTreeNode res; + + if ((res = Find(_Root, myKey)) != null && res.Values.Contains(myValue)) + { + res.Values.Remove(myValue); + _ValueCount--; + + return (res.Values.Count == 0) ? Remove(myKey) : true; + } + + return false; + } + + /// + /// Currently nothing happens here. + /// + /// TODO: maybe some rebalancing + /// + public override void Optimize() + { + } + + /// + /// Resets the index by setting the root node to null and letting + /// the GC do the work. + /// + public override void Clear() + { + _Root = null; + _KeyCount = 0L; + _ValueCount = 0L; + } + + /// + /// This index does not support null as key. + /// + public override bool SupportsNullableKeys + { + get { return false; } + } + + #endregion + + #region Private Members + + /// + /// Adds a given search key and the associated value to the index. + /// + /// Starting tree node + /// Search key to be inserted + /// Associated value + /// Define what happens if the key exists + private void Add(BinaryTreeNode myTreeNode, + IComparable myKey, + Int64 myValue, + IndexAddStrategy myIndexAddStrategy) + { + if (myKey.CompareTo(myTreeNode.Key) == 0) // key already exists + { + switch (myIndexAddStrategy) + { + case IndexAddStrategy.REPLACE: + // replace the value + _ValueCount -= myTreeNode.Values.Count; + myTreeNode.Values = new HashSet() { myValue }; + _ValueCount++; + break; + case IndexAddStrategy.MERGE: + // add the new value to the existing ones + if (myTreeNode.Values.Add(myValue)) + { + _ValueCount++; + } + break; + default: // UNIQUE + throw new IndexKeyExistsException( + String.Format("key {0} already exists in binary tree", myKey)); + } + } + else + { + if (myKey.CompareTo(myTreeNode.Key) == -1) // new key is lower + { + if (myTreeNode.Left == null) + { + myTreeNode.Left = new BinaryTreeNode(myKey, new HashSet() { myValue }); + _ValueCount++; + _KeyCount++; + } + else + { + Add(myTreeNode.Left, myKey, myValue, myIndexAddStrategy); + } + } + else // new key is greater + { + if (myTreeNode.Right == null) + { + myTreeNode.Right = new BinaryTreeNode(myKey, new HashSet() { myValue }); + _ValueCount++; + _KeyCount++; + } + else + { + Add(myTreeNode.Right, myKey, myValue, myIndexAddStrategy); + } + } + } + } + + /// + /// Checks if a given key exists in the tree + /// + /// Starting Node + /// Search key + /// The tree node if the key exists or null if it does not. + private BinaryTreeNode Find(BinaryTreeNode myTreeNode, + IComparable myKey) + { + if (myTreeNode == null) // no way + { + return null; + } + else if (myKey.CompareTo(myTreeNode.Key) == -1) // lower + { + return Find(myTreeNode.Left, myKey); + } + else if (myKey.CompareTo(myTreeNode.Key) == 1) // greater + { + return Find(myTreeNode.Right, myKey); + } + else // match + { + return myTreeNode; + } + + } + + /// + /// Removes a given key from the tree, if it exists. + /// Returns the new (or existing) root node. + /// + /// Starting tree node + /// Search key + /// Root node as a result of back propagation + private BinaryTreeNode Remove(BinaryTreeNode myTreeNode, + IComparable myKey, + ref bool myRemoved) + { + if (myTreeNode == null) + { + myRemoved = false; + return null; + } + else if (myKey.CompareTo(myTreeNode.Key) == -1) // lower + { + myTreeNode.Left = Remove(myTreeNode.Left, myKey, ref myRemoved); + } + else if (myKey.CompareTo(myTreeNode.Key) == 1) // greater + { + myTreeNode.Right = Remove(myTreeNode.Right, myKey, ref myRemoved); + } + else if (myTreeNode.Left != null && myTreeNode.Right != null) + { + // get minimum tree node in right subtree + var minRightTree = FindMinNodeIn(myTreeNode.Right); + /* + * replace key and value of the current node with key and value + * of the minimum node in the right subtree + */ + _KeyCount--; // update key count + myTreeNode.Key = minRightTree.Key; + + _ValueCount -= myTreeNode.Values.Count; // update value count + myTreeNode.Values = minRightTree.Values; + + // remove the minimum tree node in the right subtree + myTreeNode.Right = RemoveMinIn(myTreeNode.Right); + + // node has been removed + myRemoved = true; + + } + else + { + /* + * if there is a left child, we replace the current node with that one + * and of not, we replace the current with the right child node + */ + _KeyCount--; // update key count + _ValueCount -= myTreeNode.Values.Count; // update value count + + myTreeNode = (myTreeNode.Left != null) ? myTreeNode.Left : myTreeNode.Right; + + // node has been removed + myRemoved = true; + } + + return myTreeNode; + } + + /// + /// Returns the minimum BinaryTreeNode in a subtree. The minimum node + /// is the most left node in the subtree. + /// + /// Starting node + /// The smallest in the given subtree + private BinaryTreeNode FindMinNodeIn(BinaryTreeNode myTreeNode) + { + if (myTreeNode.Left != null) + { + // go deeper in the left subtree + return FindMinNodeIn(myTreeNode.Left); + } + else + { + // got the minimum + return myTreeNode; + } + } + + /// + /// Removes the minium BinaryTreeNode in a tree. The minimum node + /// is the most left node in the subtree. + /// + /// Starting node + /// The new left child node, if treenode has been deleted. + private BinaryTreeNode RemoveMinIn(BinaryTreeNode myTreeNode) + { + if (myTreeNode != null) + { + if (myTreeNode.Left != null) + { + myTreeNode.Left = RemoveMinIn(myTreeNode.Left); + return myTreeNode; + } + else + { + return myTreeNode.Right; + } + } + return null; + } + + /// + /// Traverses the tree in-order: Left-Root-Right + /// + /// This means the keys are returned sorted. + /// + /// Starting tree node + /// stores the keys visited during traversal + private void TraverseInOrder(BinaryTreeNode myTreeNode, ref List myResult) + { + if (myTreeNode.Left != null) + { + TraverseInOrder(myTreeNode.Left, ref myResult); + } + myResult.Add(myTreeNode.Key); + + if (myTreeNode.Right != null) + { + TraverseInOrder(myTreeNode.Right, ref myResult); + } + } + + #endregion + + } +} diff --git a/BinaryTreeIndex/BinaryTreeIndex.csproj b/BinaryTreeIndex/BinaryTreeIndex.csproj new file mode 100644 index 0000000..3b67061 --- /dev/null +++ b/BinaryTreeIndex/BinaryTreeIndex.csproj @@ -0,0 +1,72 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {F49E824F-7917-44A2-A4B4-7167F61C2836} + Library + Properties + BinaryTreeIndex + BinaryTreeIndex + v4.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + {EA1F7F6C-C8C9-4529-998D-B86701FFA1DE} + ErrorHandling + + + {C6DDFD34-176E-48AC-998F-854F98CD28BB} + IPluginable + + + {A1BD782F-F3C4-4820-8B00-FDBDAADAE37D} + PropertyHyperGraph + + + {823E8AF4-CF92-4E74-8ABD-38693279EB1E} + ISonesIndex + + + + + \ No newline at end of file diff --git a/BinaryTreeIndex/Properties/AssemblyInfo.cs b/BinaryTreeIndex/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..abc7b1f --- /dev/null +++ b/BinaryTreeIndex/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BinaryTreeIndex")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("BinaryTreeIndex")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("810b3a47-bc40-4cc6-a88f-9bf8ef0b9e94")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/BinaryTreeIndex/bin/Debug/BinaryTreeIndex.dll b/BinaryTreeIndex/bin/Debug/BinaryTreeIndex.dll new file mode 100644 index 0000000..726780b Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/BinaryTreeIndex.dll differ diff --git a/BinaryTreeIndex/bin/Debug/BinaryTreeIndex.pdb b/BinaryTreeIndex/bin/Debug/BinaryTreeIndex.pdb new file mode 100644 index 0000000..3be4ed9 Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/BinaryTreeIndex.pdb differ diff --git a/BinaryTreeIndex/bin/Debug/CollectionWrapper.dll b/BinaryTreeIndex/bin/Debug/CollectionWrapper.dll new file mode 100644 index 0000000..382730b Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/CollectionWrapper.dll differ diff --git a/BinaryTreeIndex/bin/Debug/CollectionWrapper.pdb b/BinaryTreeIndex/bin/Debug/CollectionWrapper.pdb new file mode 100644 index 0000000..5734718 Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/CollectionWrapper.pdb differ diff --git a/BinaryTreeIndex/bin/Debug/ErrorHandling.dll b/BinaryTreeIndex/bin/Debug/ErrorHandling.dll new file mode 100644 index 0000000..d7b9a7a Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/ErrorHandling.dll differ diff --git a/BinaryTreeIndex/bin/Debug/ErrorHandling.pdb b/BinaryTreeIndex/bin/Debug/ErrorHandling.pdb new file mode 100644 index 0000000..d7781ef Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/ErrorHandling.pdb differ diff --git a/BinaryTreeIndex/bin/Debug/IPluginable.dll b/BinaryTreeIndex/bin/Debug/IPluginable.dll new file mode 100644 index 0000000..3296bff Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/IPluginable.dll differ diff --git a/BinaryTreeIndex/bin/Debug/IPluginable.pdb b/BinaryTreeIndex/bin/Debug/IPluginable.pdb new file mode 100644 index 0000000..1e9fe80 Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/IPluginable.pdb differ diff --git a/BinaryTreeIndex/bin/Debug/ISonesIndex.dll b/BinaryTreeIndex/bin/Debug/ISonesIndex.dll new file mode 100644 index 0000000..53ec1c3 Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/ISonesIndex.dll differ diff --git a/BinaryTreeIndex/bin/Debug/ISonesIndex.pdb b/BinaryTreeIndex/bin/Debug/ISonesIndex.pdb new file mode 100644 index 0000000..380d2e0 Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/ISonesIndex.pdb differ diff --git a/BinaryTreeIndex/bin/Debug/NewFastSerializer.dll b/BinaryTreeIndex/bin/Debug/NewFastSerializer.dll new file mode 100644 index 0000000..ceb76c1 Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/NewFastSerializer.dll differ diff --git a/BinaryTreeIndex/bin/Debug/NewFastSerializer.pdb b/BinaryTreeIndex/bin/Debug/NewFastSerializer.pdb new file mode 100644 index 0000000..81da583 Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/NewFastSerializer.pdb differ diff --git a/BinaryTreeIndex/bin/Debug/PropertyHyperGraph.dll b/BinaryTreeIndex/bin/Debug/PropertyHyperGraph.dll new file mode 100644 index 0000000..391e4ce Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/PropertyHyperGraph.dll differ diff --git a/BinaryTreeIndex/bin/Debug/PropertyHyperGraph.pdb b/BinaryTreeIndex/bin/Debug/PropertyHyperGraph.pdb new file mode 100644 index 0000000..d4750a7 Binary files /dev/null and b/BinaryTreeIndex/bin/Debug/PropertyHyperGraph.pdb differ diff --git a/BinaryTreeIndex/obj/Debug/BinaryTreeIndex.csproj.FileListAbsolute.txt b/BinaryTreeIndex/obj/Debug/BinaryTreeIndex.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..8a2ee11 --- /dev/null +++ b/BinaryTreeIndex/obj/Debug/BinaryTreeIndex.csproj.FileListAbsolute.txt @@ -0,0 +1,17 @@ +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\BinaryTreeIndex.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\BinaryTreeIndex.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\ErrorHandling.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\IPluginable.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\ISonesIndex.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\PropertyHyperGraph.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\CollectionWrapper.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\NewFastSerializer.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\ErrorHandling.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\IPluginable.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\PropertyHyperGraph.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\ISonesIndex.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\CollectionWrapper.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex\bin\Debug\NewFastSerializer.pdb +S:\sones-bstindex-tutorial\BinaryTreeIndex\obj\Debug\ResolveAssemblyReference.cache +S:\sones-bstindex-tutorial\BinaryTreeIndex\obj\Debug\BinaryTreeIndex.dll +S:\sones-bstindex-tutorial\BinaryTreeIndex\obj\Debug\BinaryTreeIndex.pdb diff --git a/BinaryTreeIndex/obj/Debug/BinaryTreeIndex.dll b/BinaryTreeIndex/obj/Debug/BinaryTreeIndex.dll new file mode 100644 index 0000000..726780b Binary files /dev/null and b/BinaryTreeIndex/obj/Debug/BinaryTreeIndex.dll differ diff --git a/BinaryTreeIndex/obj/Debug/BinaryTreeIndex.pdb b/BinaryTreeIndex/obj/Debug/BinaryTreeIndex.pdb new file mode 100644 index 0000000..3be4ed9 Binary files /dev/null and b/BinaryTreeIndex/obj/Debug/BinaryTreeIndex.pdb differ diff --git a/BinaryTreeIndex/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/BinaryTreeIndex/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100644 index 0000000..0c626af Binary files /dev/null and b/BinaryTreeIndex/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/README b/README index e69de29..211e792 100644 --- a/README +++ b/README @@ -0,0 +1,9 @@ +binary search tree index tutorial + +This is the source corresponding to the custom index tutorial which can be found here: + +http://developers.sones.de/wiki/doku.php?id=documentation:plugins:database:indices + +It can be seen as some kind of template to implement own indices which can be integrated in the sones GraphDB. + +Questions are alway welcome -> http://forum.sones.com \ No newline at end of file diff --git a/gitignore b/gitignore new file mode 100644 index 0000000..4906cee --- /dev/null +++ b/gitignore @@ -0,0 +1,932 @@ + + + + + + + + + + + + .gitignore at master from sones/sones - GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Markdown Cheat Sheet

+ +
+ +
+
+

Format Text

+

Headers

+
+# This is an <h1> tag
+## This is an <h2> tag
+###### This is an <h6> tag
+

Text styles

+
+*This text will be italic*
+_This will also be italic_
+**This text will be bold**
+__This will also be bold__
+
+*You **can** combine them*
+
+
+
+

Lists

+

Unordered

+
+* Item 1
+* Item 2
+  * Item 2a
+  * Item 2b
+

Ordered

+
+1. Item 1
+2. Item 2
+3. Item 3
+   * Item 3a
+   * Item 3b
+
+
+

Miscellaneous

+

Images

+
+![GitHub Logo](/images/logo.png)
+Format: ![Alt Text](url)
+
+

Links

+
+http://github.com - automatic!
+[GitHub](http://github.com)
+

Blockquotes

+
+As Kanye West said:
+> We're living the future so
+> the present is our past.
+
+
+
+
+ +

Code Examples in Markdown

+
+

Syntax highlighting with GFM

+
+```javascript
+function fancyAlert(arg) {
+  if(arg) {
+    $.facebox({div:'#foo'})
+  }
+}
+```
+
+
+

Or, indent your code 4 spaces

+
+Here is a Python code example
+without syntax highlighting:
+
+    def foo:
+      if not bar:
+        return true
+
+
+

Inline code for comments

+
+I think you should use an
+`<addr>` element here instead.
+
+
+ +
+ + + + + + + + + +