Beispiel #1
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldCloseUnexhaustedCursorsOnReaderClose() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldCloseUnexhaustedCursorsOnReaderClose()
        {
            // GIVEN
            GBPTree <LabelScanKey, LabelScanValue> index = mock(typeof(GBPTree));
            RawCursor <Hit <LabelScanKey, LabelScanValue>, IOException> cursor1 = mock(typeof(RawCursor));

            when(cursor1.Next()).thenReturn(false);
            RawCursor <Hit <LabelScanKey, LabelScanValue>, IOException> cursor2 = mock(typeof(RawCursor));

            when(cursor2.Next()).thenReturn(false);
            when(index.Seek(any(typeof(LabelScanKey)), any(typeof(LabelScanKey)))).thenReturn(cursor1, cursor2);

            // WHEN
            using (NativeLabelScanReader reader = new NativeLabelScanReader(index))
            {
                // first check test invariants
                reader.NodesWithLabel(LABEL_ID);
                reader.NodesWithLabel(LABEL_ID);
                verify(cursor1, never()).close();
                verify(cursor2, never()).close();
            }

            // THEN
            verify(cursor1, times(1)).close();
            verify(cursor2, times(1)).close();
        }
Beispiel #2
0
        // Timeout because test verify no infinite loop
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test(timeout = 10_000L) public void shouldHandleDescendingWithEmptyRange() throws java.io.IOException
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldHandleDescendingWithEmptyRange()
        {
            long[] seeds = new long[] { 0, 1, 4 };
            using (GBPTree <KEY, VALUE> index = CreateIndex())
            {
                // Write
                using (Writer <KEY, VALUE> writer = CreateWriter(index))
                {
                    foreach (long seed in seeds)
                    {
                        KEY   key   = _layout.key(seed);
                        VALUE value = _layout.value(0);
                        writer.Put(key, value);
                    }
                }

                KEY from = _layout.key(3);
                KEY to   = _layout.key(1);
                using (RawCursor <Hit <KEY, VALUE>, IOException> seek = index.Seek(from, to))
                {
                    assertFalse(seek.Next());
                }
                index.Checkpoint(Org.Neo4j.Io.pagecache.IOLimiter_Fields.Unlimited);
            }
        }
Beispiel #3
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: private org.neo4j.cursor.RawCursor<org.neo4j.index.internal.gbptree.Hit<KEY,VALUE>, java.io.IOException> scan(org.neo4j.index.internal.gbptree.GBPTree<KEY,VALUE> tree) throws java.io.IOException
        private RawCursor <Hit <KEY, VALUE>, IOException> Scan(GBPTree <KEY, VALUE> tree)
        {
            KEY lowest = Layout.newKey();

            lowest.initialize(long.MinValue);
            lowest.initValueAsLowest(0, ValueGroup.UNKNOWN);
            KEY highest = Layout.newKey();

            highest.initialize(long.MaxValue);
            highest.initValueAsHighest(0, ValueGroup.UNKNOWN);
            return(tree.Seek(lowest, highest));
        }
Beispiel #4
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldHandleRemoveEntireTree() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldHandleRemoveEntireTree()
        {
            // given
            using (GBPTree <KEY, VALUE> index = CreateIndex())
            {
                int numberOfNodes = 200_000;
                using (Writer <KEY, VALUE> writer = CreateWriter(index))
                {
                    for (int i = 0; i < numberOfNodes; i++)
                    {
                        writer.Put(Key(i), Value(i));
                    }
                }

                // when
                BitArray removed = new BitArray();
                using (Writer <KEY, VALUE> writer = CreateWriter(index))
                {
                    for (int i = 0; i < numberOfNodes - numberOfNodes / 10; i++)
                    {
                        int candidate;
                        do
                        {
                            candidate = Random.Next(max(1, Random.Next(numberOfNodes)));
                        } while (removed.Get(candidate));
                        removed.Set(candidate, true);

                        writer.Remove(Key(candidate));
                    }
                }

                int next = 0;
                using (Writer <KEY, VALUE> writer = CreateWriter(index))
                {
                    for (int i = 0; i < numberOfNodes / 10; i++)
                    {
                        next = removed.nextClearBit(next);
                        removed.Set(next, true);
                        writer.Remove(Key(next));
                    }
                }

                // then
                using (RawCursor <Hit <KEY, VALUE>, IOException> seek = index.Seek(Key(0), Key(numberOfNodes)))
                {
                    assertFalse(seek.Next());
                }

                // and finally
                index.ConsistencyCheck();
            }
        }
Beispiel #5
0
        /* Randomized tests */

//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldSplitCorrectly() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldSplitCorrectly()
        {
            // GIVEN
            using (GBPTree <KEY, VALUE> index = index())
            {
                // WHEN
                int         count = 1_000;
                IList <KEY> seen  = new List <KEY>(count);
                using (Writer <KEY, VALUE> writer = index.Writer())
                {
                    for (int i = 0; i < count; i++)
                    {
                        KEY key;
                        do
                        {
                            key = key(_random.Next(100_000));
                        } while (ListContains(seen, key));
                        VALUE value = value(i);
                        writer.Put(key, value);
                        seen.Add(key);
                    }
                }

                // THEN
                using (RawCursor <Hit <KEY, VALUE>, IOException> cursor = index.Seek(Key(0), Key(long.MaxValue)))
                {
                    long prev = -1;
                    while (cursor.Next())
                    {
                        KEY  hit     = cursor.get().key();
                        long hitSeed = _layout.keySeed(hit);
                        if (hitSeed < prev)
                        {
                            fail(hit + " smaller than prev " + prev);
                        }
                        prev = hitSeed;
                        assertTrue(RemoveFromList(seen, hit));
                    }

                    if (seen.Count > 0)
                    {
                        fail("expected hits " + seen);
                    }
                }
            }
        }
Beispiel #6
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: private void shouldWriteAndReadEntriesOfRandomSizes(int minKeySize, int maxKeySize, int minValueSize, int maxValueSize) throws java.io.IOException
        private void ShouldWriteAndReadEntriesOfRandomSizes(int minKeySize, int maxKeySize, int minValueSize, int maxValueSize)
        {
            // given
            using (GBPTree <RawBytes, RawBytes> tree = CreateIndex(Layout()))
            {
                // when
                ISet <string> generatedStrings             = new HashSet <string>();
                IList <Pair <RawBytes, RawBytes> > entries = new List <Pair <RawBytes, RawBytes> >();
                using (Writer <RawBytes, RawBytes> writer = tree.Writer())
                {
                    for (int i = 0; i < 1_000; i++)
                    {
                        // value, based on i
                        RawBytes value = new RawBytes();
                        value.Bytes = new sbyte[Random.Next(minValueSize, maxValueSize)];
                        Random.NextBytes(value.Bytes);

                        // key, randomly generated
                        string @string;
                        do
                        {
                            @string = Random.nextAlphaNumericString(minKeySize, maxKeySize);
                        } while (!generatedStrings.Add(@string));
                        RawBytes key = new RawBytes();
                        key.Bytes = UTF8.encode(@string);
                        entries.Add(Pair.of(key, value));

                        // write
                        writer.Put(key, value);
                    }
                }

                // then
                foreach (Pair <RawBytes, RawBytes> entry in entries)
                {
                    using (RawCursor <Hit <RawBytes, RawBytes>, IOException> seek = tree.Seek(entry.First(), entry.First()))
                    {
                        assertTrue(seek.Next());
                        assertArrayEquals(entry.First().Bytes, seek.get().key().bytes);
                        assertArrayEquals(entry.Other().Bytes, seek.get().value().bytes);
                        assertFalse(seek.Next());
                    }
                }
            }
        }
Beispiel #7
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unchecked") @Test public void shouldFindMultipleNodesInEachRange() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldFindMultipleNodesInEachRange()
        {
            // GIVEN
            GBPTree <LabelScanKey, LabelScanValue> index = mock(typeof(GBPTree));
            RawCursor <Hit <LabelScanKey, LabelScanValue>, IOException> cursor = mock(typeof(RawCursor));

            when(cursor.Next()).thenReturn(true, true, true, false);
            when(cursor.get()).thenReturn(Hit(0, 0b1000_1000__1100_0010L), Hit(1, 0b0000_0010__0000_1000L), Hit(3, 0b0010_0000__1010_0001L), null);
            when(index.Seek(any(typeof(LabelScanKey)), any(typeof(LabelScanKey)))).thenReturn(cursor);
            using (NativeLabelScanReader reader = new NativeLabelScanReader(index))
            {
                // WHEN
                LongIterator iterator = reader.NodesWithLabel(LABEL_ID);

                // THEN
                assertArrayEquals(new long[] { 1, 6, 7, 11, 15, 64 + 3, 64 + 9, 192 + 0, 192 + 5, 192 + 7, 192 + 13 }, asArray(iterator));
            }
        }
Beispiel #8
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldStartFromGivenId() throws java.io.IOException
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldStartFromGivenId()
        {
            // given
            GBPTree <LabelScanKey, LabelScanValue> index = mock(typeof(GBPTree));
            RawCursor <Hit <LabelScanKey, LabelScanValue>, IOException> cursor = mock(typeof(RawCursor));

            when(cursor.Next()).thenReturn(true, true, false);
            when(cursor.get()).thenReturn(Hit(1, 0b0001_1000__0101_1110L), Hit(3, 0b0010_0000__1010_0001L), null);
            when(index.Seek(any(typeof(LabelScanKey)), any(typeof(LabelScanKey)))).thenReturn(cursor);

            // when
            long fromId = LabelScanValue.RangeSize + 3;

            using (NativeLabelScanReader reader = new NativeLabelScanReader(index), PrimitiveLongResourceIterator iterator = reader.NodesWithAnyOfLabels(fromId, LABEL_ID))
            {
                // then
                assertArrayEquals(new long[] { 64 + 4, 64 + 6, 64 + 11, 64 + 12, 192 + 0, 192 + 5, 192 + 7, 192 + 13 }, asArray(iterator));
            }
        }
Beispiel #9
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldSeeSimpleInsertions() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldSeeSimpleInsertions()
        {
            using (GBPTree <KEY, VALUE> index = index())
            {
                int count = 1000;
                using (Writer <KEY, VALUE> writer = index.Writer())
                {
                    for (int i = 0; i < count; i++)
                    {
                        writer.Put(Key(i), Value(i));
                    }
                }

                using (RawCursor <Hit <KEY, VALUE>, IOException> cursor = index.Seek(Key(0), Key(long.MaxValue)))
                {
                    for (int i = 0; i < count; i++)
                    {
                        assertTrue(cursor.Next());
                        AssertEqualsKey(Key(i), cursor.get().key());
                    }
                    assertFalse(cursor.Next());
                }
            }
        }
Beispiel #10
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldSupportMultipleOpenCursorsConcurrently() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldSupportMultipleOpenCursorsConcurrently()
        {
            // GIVEN
            GBPTree <LabelScanKey, LabelScanValue> index = mock(typeof(GBPTree));
            RawCursor <Hit <LabelScanKey, LabelScanValue>, IOException> cursor1 = mock(typeof(RawCursor));

            when(cursor1.Next()).thenReturn(false);
            RawCursor <Hit <LabelScanKey, LabelScanValue>, IOException> cursor2 = mock(typeof(RawCursor));

            when(cursor2.Next()).thenReturn(false);
            when(index.Seek(any(typeof(LabelScanKey)), any(typeof(LabelScanKey)))).thenReturn(cursor1, cursor2);

            // WHEN
            using (NativeLabelScanReader reader = new NativeLabelScanReader(index))
            {
                // first check test invariants
                verify(cursor1, never()).close();
                verify(cursor2, never()).close();
                LongIterator first  = reader.NodesWithLabel(LABEL_ID);
                LongIterator second = reader.NodesWithLabel(LABEL_ID);

                // getting the second iterator should not have closed the first one
                verify(cursor1, never()).close();
                verify(cursor2, never()).close();

                // exhausting the first one should have closed only the first one
                Exhaust(first);
                verify(cursor1, times(1)).close();
                verify(cursor2, never()).close();

                // exhausting the second one should close it
                Exhaust(second);
                verify(cursor1, times(1)).close();
                verify(cursor2, times(1)).close();
            }
        }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: static void verify(org.neo4j.storageengine.api.NodePropertyAccessor nodePropertyAccessor, IndexLayout<SpatialIndexKey,NativeIndexValue> layout, org.neo4j.index.internal.gbptree.GBPTree<SpatialIndexKey,NativeIndexValue> tree, org.neo4j.storageengine.api.schema.StoreIndexDescriptor descriptor) throws org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException
        internal static void Verify(NodePropertyAccessor nodePropertyAccessor, IndexLayout <SpatialIndexKey, NativeIndexValue> layout, GBPTree <SpatialIndexKey, NativeIndexValue> tree, StoreIndexDescriptor descriptor)
        {
            SpatialIndexKey from = layout.newKey();
            SpatialIndexKey to   = layout.newKey();

            InitializeKeys(from, to);
            try
            {
                using (RawCursor <Hit <SpatialIndexKey, NativeIndexValue>, IOException> seek = tree.Seek(from, to))
                {
                    ScanAndVerifyDuplicates(nodePropertyAccessor, descriptor, seek);
                }
            }
            catch (IOException e)
            {
                throw new UncheckedIOException(e);
            }
        }
Beispiel #12
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public void verifyContent(java.io.File storeFile) throws java.io.IOException
		 public override void VerifyContent( File storeFile )
		 {
			  PageCache pageCache = _pageCacheRule.getPageCache( GlobalFs.get() );
			  using ( GBPTree<MutableLong, MutableLong> tree = ( new GBPTreeBuilder<MutableLong, MutableLong>( pageCache, storeFile, Layout ) ).build() )
			  {
					{
						 // WHEN reading from the tree
						 // THEN initial keys should be there
						 tree.ConsistencyCheck();
						 using ( RawCursor<Hit<MutableLong, MutableLong>, IOException> cursor = tree.Seek( Layout.key( 0 ), Layout.key( long.MaxValue ) ) )
						 {
							  foreach ( long? expectedKey in _initialKeys )
							  {
									AssertHit( cursor, expectedKey );
							  }
							  assertFalse( cursor.Next() );
						 }
					}

					{
						 // WHEN writing more to the tree
						 // THEN we should not see any format conflicts
						 using ( Writer<MutableLong, MutableLong> writer = tree.Writer() )
						 {
							  while ( _keysToAdd.Count > 0 )
							  {
									int next = _random.Next( _keysToAdd.Count );
									Put( writer, _keysToAdd[next] );
									_keysToAdd.RemoveAt( next );
							  }
						 }
					}

					{
						 // WHEN reading from the tree again
						 // THEN all keys including newly added should be there
						 tree.ConsistencyCheck();
						 using ( RawCursor<Hit<MutableLong, MutableLong>, IOException> cursor = tree.Seek( Layout.key( 0 ), Layout.key( 2 * INITIAL_KEY_COUNT ) ) )
						 {
							  foreach ( long? expectedKey in _allKeys )
							  {
									AssertHit( cursor, expectedKey );
							  }
							  assertFalse( cursor.Next() );
						 }
					}

					{
						 // WHEN randomly removing half of tree content
						 // THEN we should not see any format conflicts
						 using ( Writer<MutableLong, MutableLong> writer = tree.Writer() )
						 {
							  int size = _allKeys.Count;
							  while ( _allKeys.Count > size / 2 )
							  {
									int next = _random.Next( _allKeys.Count );
									MutableLong key = Layout.key( _allKeys[next] );
									writer.Remove( key );
									_allKeys.RemoveAt( next );
							  }
						 }
					}

					{
						 // WHEN reading from the tree after remove
						 // THEN we should see everything that is left in the tree
						 tree.ConsistencyCheck();
						 using ( RawCursor<Hit<MutableLong, MutableLong>, IOException> cursor = tree.Seek( Layout.key( 0 ), Layout.key( 2 * INITIAL_KEY_COUNT ) ) )
						 {
							  foreach ( long? expectedKey in _allKeys )
							  {
									AssertHit( cursor, expectedKey );
							  }
							  assertFalse( cursor.Next() );
						 }
					}
			  }
		 }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: private void doShouldRecoverFromAnything(boolean replayRecoveryExactlyFromCheckpoint) throws Exception
        private void DoShouldRecoverFromAnything(bool replayRecoveryExactlyFromCheckpoint)
        {
            AssertInitialized();
            // GIVEN
            // a tree which has had random updates and checkpoints in it, load generated with specific seed
            File           file                = _directory.file("index");
            IList <Action> load                = GenerateLoad();
            IList <Action> shuffledLoad        = RandomCausalAwareShuffle(load);
            int            lastCheckPointIndex = IndexOfLastCheckpoint(load);

            {
                // _,_,_,_,_,_,_,c,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,c,_,_,_,_,_,_,_,_,_,_,_
                //                                                 ^             ^
                //                                                 |             |------------ crash flush index
                //                                                 |-------------------------- last checkpoint index
                //

                PageCache            pageCache = CreatePageCache();
                GBPTree <KEY, VALUE> index     = CreateIndex(pageCache, file);
                // Execute all actions up to and including last checkpoint ...
                Execute(shuffledLoad.subList(0, lastCheckPointIndex + 1), index);
                // ... a random amount of the remaining "unsafe" actions ...
                int numberOfRemainingActions = shuffledLoad.Count - lastCheckPointIndex - 1;
                int crashFlushIndex          = lastCheckPointIndex + _random.Next(numberOfRemainingActions) + 1;
                Execute(shuffledLoad.subList(lastCheckPointIndex + 1, crashFlushIndex), index);
                // ... flush ...
                pageCache.FlushAndForce();
                // ... execute the remaining actions
                Execute(shuffledLoad.subList(crashFlushIndex, shuffledLoad.Count), index);
                // ... and finally crash
                _fs.snapshot(throwing(() =>
                {
                    index.Dispose();
                    pageCache.Close();
                }));
            }

            // WHEN doing recovery
            IList <Action> recoveryActions;

            if (replayRecoveryExactlyFromCheckpoint)
            {
                recoveryActions = recoveryActions(load, lastCheckPointIndex + 1);
            }
            else
            {
                recoveryActions = recoveryActions(load, _random.Next(lastCheckPointIndex + 1));
            }

            // first crashing during recovery
            int numberOfCrashesDuringRecovery = _random.intBetween(0, 3);

            for (int i = 0; i < numberOfCrashesDuringRecovery; i++)
            {
                using (PageCache pageCache = CreatePageCache(), GBPTree <KEY, VALUE> index = CreateIndex(pageCache, file))
                {
                    int numberOfActionsToRecoverBeforeCrashing = _random.intBetween(1, recoveryActions.Count);
                    Recover(recoveryActions.subList(0, numberOfActionsToRecoverBeforeCrashing), index);
                    // ... crash
                }
            }

            // to finally apply all actions after last checkpoint and verify tree
            using (PageCache pageCache = CreatePageCache(), GBPTree <KEY, VALUE> index = CreateIndex(pageCache, file))
            {
                Recover(recoveryActions, index);

                // THEN
                // we should end up with a consistent index containing all the stuff load says
                index.ConsistencyCheck();
                long[] aggregate = ExpectedSortedAggregatedDataFromGeneratedLoad(load);
                using (RawCursor <Hit <KEY, VALUE>, IOException> cursor = index.Seek(Key(long.MinValue), Key(long.MaxValue)))
                {
                    for (int i = 0; i < aggregate.Length;)
                    {
                        assertTrue(cursor.Next());
                        Hit <KEY, VALUE> hit = cursor.get();
                        AssertEqualsKey(Key(aggregate[i++]), hit.Key());
                        AssertEqualsValue(Value(aggregate[i++]), hit.Value());
                    }
                    assertFalse(cursor.Next());
                }
            }
        }
Beispiel #14
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldStayCorrectAfterRandomModifications() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldStayCorrectAfterRandomModifications()
        {
            // GIVEN
            using (GBPTree <KEY, VALUE> index = CreateIndex())
            {
                IComparer <KEY>          keyComparator = _layout;
                IDictionary <KEY, VALUE> data          = new SortedDictionary <KEY, VALUE>(keyComparator);
                int count = 100;
                int totalNumberOfRounds = 10;
                for (int i = 0; i < count; i++)
                {
                    data[RandomKey(Random.random())] = RandomValue(Random.random());
                }

                // WHEN
                using (Writer <KEY, VALUE> writer = CreateWriter(index))
                {
                    foreach (KeyValuePair <KEY, VALUE> entry in data.SetOfKeyValuePairs())
                    {
                        writer.Put(entry.Key, entry.Value);
                    }
                }

                for (int round = 0; round < totalNumberOfRounds; round++)
                {
                    // THEN
                    for (int i = 0; i < count; i++)
                    {
                        KEY first  = RandomKey(Random.random());
                        KEY second = RandomKey(Random.random());
                        KEY from;
                        KEY to;
                        if (_layout.keySeed(first) < _layout.keySeed(second))
                        {
                            from = first;
                            to   = second;
                        }
                        else
                        {
                            from = second;
                            to   = first;
                        }
                        IDictionary <KEY, VALUE> expectedHits = expectedHits(data, from, to, keyComparator);
                        using (RawCursor <Hit <KEY, VALUE>, IOException> result = index.Seek(from, to))
                        {
                            while (result.Next())
                            {
                                KEY key = result.get().key();
                                if (expectedHits.Remove(key) == null)
                                {
                                    fail("Unexpected hit " + key + " when searching for " + from + " - " + to);
                                }

                                assertTrue(keyComparator.Compare(key, from) >= 0);
                                if (keyComparator.Compare(from, to) != 0)
                                {
                                    assertTrue(keyComparator.Compare(key, to) < 0);
                                }
                            }
                            if (expectedHits.Count > 0)
                            {
                                fail("There were results which were expected to be returned, but weren't:" + expectedHits + " when searching range " + from + " - " + to);
                            }
                        }
                    }

                    index.Checkpoint(Org.Neo4j.Io.pagecache.IOLimiter_Fields.Unlimited);
                    RandomlyModifyIndex(index, data, Random.random(), (double)round / totalNumberOfRounds);
                }

                // and finally
                index.ConsistencyCheck();
            }
        }