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
        }
        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
        }
        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
        }
        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<Int64>() { 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
        }
        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
        }
        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
        }
        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
        }
        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<Int64> 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
        }
        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
        }
        public virtual void ContainsKey_False()
        {
            #region data

            var idx = new BinaryTreeIndex();

            var key_1 = 1;

            #endregion

            #region

            Assert.IsFalse(idx.ContainsKey(key_1));

            #endregion
        }
        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<Int64>() { propertyID });

            // create a vertex
            var v = new InMemoryVertex(vertexID,
                1L,
                1L,
                null,
                null,
                null,
                "dummy",
                DateTime.Now.Ticks,
                DateTime.Now.Ticks,
                new Dictionary<long, IComparable>() { { 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
        }
        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<Int64>() { propertyID });

            // create a vertex
            var v = new InMemoryVertex(vertexID,
                1L,
                1L,
                null,
                null,
                null,
                "dummy",
                DateTime.Now.Ticks,
                DateTime.Now.Ticks,
                new Dictionary<long, IComparable>() { { 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
        }
        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
        }
        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
        }
        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
        }
        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
        }
        public virtual void Init_CheckPrivateMemberEquality()
        {
            #region data

            var idx = new BinaryTreeIndex();

            #endregion

            #region

            // init the index with some propertyIDs
            var definedPropertyIDs = new List<Int64>() { 0L, 1L };
            idx.Init(definedPropertyIDs);

            // use some reflection action to get the private member of the index instance
            var indexedPropertyIDs = (List<Int64>)idx.GetType().GetField("_PropertyIDs", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(idx);

            CollectionAssert.AreEqual(definedPropertyIDs, indexedPropertyIDs, "indexed propertyIDs do not match");

            #endregion
        }
        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<Int64> result;
            Assert.IsFalse(idx.TryGetValues(key_3, out result));
            Assert.IsNull(result);

            #endregion
        }
        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
        }
        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<Int64>() { 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
        }
        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
        }
        public void ValueCountTest()
        {
            #region data

            var idx = new BinaryTreeIndex();

            var kvp = new List<KeyValuePair<IComparable, Int64>>()
            {
                new KeyValuePair<IComparable, Int64>(1, 1),
                new KeyValuePair<IComparable, Int64>(1, 2),
                new KeyValuePair<IComparable, Int64>(2, 3),
                new KeyValuePair<IComparable, Int64>(2, 4),
                new KeyValuePair<IComparable, Int64>(2, 5),
            };

            idx.AddRange(kvp, IndexAddStrategy.MERGE);

            #endregion

            #region test

            Assert.That(idx.ValueCount(), Is.EqualTo(5));

            #endregion
        }
        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
        }