Search in sources :

Example 21 with MutableLong

use of org.apache.commons.lang3.mutable.MutableLong in project neo4j by neo4j.

the class TreeNodeTest method shouldInsertAndRemoveRandomKeysAndValues.

@Test
public void shouldInsertAndRemoveRandomKeysAndValues() throws Exception {
    // This test doesn't care about sorting, that's an aspect that lies outside of TreeNode, really
    // GIVEN
    node.initializeLeaf(cursor, STABLE_GENERATION, UNSTABLE_GENERATION);
    int maxKeyCount = node.leafMaxKeyCount();
    // add +1 to these to simplify some array logic in the test itself
    long[] expectedKeys = new long[maxKeyCount + 1];
    long[] expectedValues = new long[maxKeyCount + 1];
    int expectedKeyCount = 0;
    MutableLong key = layout.newKey();
    MutableLong value = layout.newValue();
    // WHEN/THEN
    for (int i = 0; i < 1000; i++) {
        if (random.nextFloat() < 0.7) {
            // 70% insert
            if (expectedKeyCount < maxKeyCount) {
                // there's room
                int position = expectedKeyCount == 0 ? 0 : random.nextInt(expectedKeyCount);
                // ensure unique
                do {
                    key.setValue(random.nextLong());
                } while (contains(expectedKeys, 0, expectedKeyCount, key.longValue()));
                node.insertKeyAt(cursor, key, position, expectedKeyCount);
                insert(expectedKeys, expectedKeyCount, key.longValue(), position);
                value.setValue(random.nextLong());
                node.insertValueAt(cursor, value, position, expectedKeyCount);
                insert(expectedValues, expectedKeyCount, value.longValue(), position);
                node.setKeyCount(cursor, ++expectedKeyCount);
            }
        } else {
            // 30% remove
            if (expectedKeyCount > 0) {
                // there are things to remove
                int position = random.nextInt(expectedKeyCount);
                node.keyAt(cursor, key, position);
                node.removeKeyAt(cursor, position, expectedKeyCount);
                long expectedKey = remove(expectedKeys, expectedKeyCount, position);
                assertEquals(expectedKey, key.longValue());
                node.valueAt(cursor, value, position);
                node.removeValueAt(cursor, position, expectedKeyCount);
                long expectedValue = remove(expectedValues, expectedKeyCount, position);
                assertEquals(expectedValue, value.longValue());
                node.setKeyCount(cursor, --expectedKeyCount);
            }
        }
    }
    // THEN
    assertEquals(expectedKeyCount, node.keyCount(cursor));
    for (int i = 0; i < expectedKeyCount; i++) {
        long expectedKey = expectedKeys[i];
        node.keyAt(cursor, key, i);
        assertEquals(expectedKey, key.longValue());
        long expectedValue = expectedValues[i];
        node.valueAt(cursor, value, i);
        assertEquals("For key " + key.longValue(), expectedValue, value.longValue());
    }
}
Also used : MutableLong(org.apache.commons.lang3.mutable.MutableLong) Test(org.junit.Test)

Example 22 with MutableLong

use of org.apache.commons.lang3.mutable.MutableLong in project neo4j by neo4j.

the class ParallelBatchImporterTest method relationships.

private InputIterable<InputRelationship> relationships(final long randomSeed, final long count, final InputIdGenerator idGenerator, final IdGroupDistribution groups) {
    return new InputIterable<InputRelationship>() {

        private int calls;

        @Override
        public InputIterator<InputRelationship> iterator() {
            calls++;
            assertTrue("Unexpected use of input iterator " + multiPassIterators + ", " + calls, multiPassIterators || (!multiPassIterators && calls == 1));
            // since we use it to compare the imported data against after the import has been completed.
            return new SimpleInputIterator<InputRelationship>("test relationships") {

                private final Random random = new Random(randomSeed);

                private final Randoms randoms = new Randoms(random, Randoms.DEFAULT);

                private int cursor;

                private final MutableLong nodeIndex = new MutableLong(-1);

                @Override
                protected InputRelationship fetchNextOrNull() {
                    if (cursor < count) {
                        Object[] properties = randomProperties(randoms, "Name " + cursor);
                        try {
                            Object startNode = idGenerator.randomExisting(random, nodeIndex);
                            Group startNodeGroup = groups.groupOf(nodeIndex.longValue());
                            Object endNode = idGenerator.randomExisting(random, nodeIndex);
                            Group endNodeGroup = groups.groupOf(nodeIndex.longValue());
                            // miss some
                            startNode = idGenerator.miss(random, startNode, 0.001f);
                            endNode = idGenerator.miss(random, endNode, 0.001f);
                            String type = idGenerator.randomType(random);
                            if (random.nextFloat() < 0.00005) {
                                // Let there be a small chance of introducing a one-off relationship
                                // with a type that no, or at least very few, other relationships have.
                                type += "_odd";
                            }
                            return new InputRelationship(sourceDescription, itemNumber, itemNumber, properties, null, startNodeGroup, startNode, endNodeGroup, endNode, type, null);
                        } finally {
                            cursor++;
                        }
                    }
                    return null;
                }
            };
        }

        @Override
        public boolean supportsMultiplePasses() {
            return multiPassIterators;
        }
    };
}
Also used : Group(org.neo4j.unsafe.impl.batchimport.input.Group) Randoms(org.neo4j.test.Randoms) MutableLong(org.apache.commons.lang3.mutable.MutableLong) SimpleInputIterator(org.neo4j.unsafe.impl.batchimport.input.SimpleInputIterator) Random(java.util.Random) InputRelationship(org.neo4j.unsafe.impl.batchimport.input.InputRelationship)

Example 23 with MutableLong

use of org.apache.commons.lang3.mutable.MutableLong in project neo4j by neo4j.

the class FormatCompatibilityTest method shouldDetectFormatChange.

@Test
public void shouldDetectFormatChange() throws Throwable {
    // GIVEN stored tree
    File storeFile = directory.file(STORE);
    try {
        unzipTo(storeFile);
    } catch (FileNotFoundException e) {
        // First time this test is run, eh?
        createAndZipTree(storeFile);
        tellDeveloperToCommitThisFormatVersion();
    }
    assertTrue(CURRENT_FORMAT_ZIP + " seems to be missing from resources directory", fsRule.get().fileExists(storeFile));
    // WHEN reading from the tree
    // THEN everything should work, otherwise there has likely been a format change
    PageCache pageCache = pageCacheRule.getPageCache(fsRule.get());
    try (GBPTree<MutableLong, MutableLong> tree = new GBPTree<>(pageCache, storeFile, new SimpleLongLayout(), 0, NO_MONITOR, NO_HEADER)) {
        try {
            tree.consistencyCheck();
            try (RawCursor<Hit<MutableLong, MutableLong>, IOException> cursor = tree.seek(new MutableLong(0), new MutableLong(KEY_COUNT))) {
                for (long expectedKey = 0; cursor.next(); expectedKey++) {
                    Hit<MutableLong, MutableLong> hit = cursor.get();
                    assertEquals(expectedKey, hit.key().longValue());
                    assertEquals(value(expectedKey), hit.value().longValue());
                }
                assertFalse(cursor.next());
            }
        } catch (Throwable t) {
            throw new AssertionError(format("If this is the single failing test for %s this failure is a strong indication that format " + "has changed without also incrementing %s.FORMAT_VERSION. " + "Please go ahead and increment the format version", TREE_CLASS_NAME, TREE_CLASS_NAME), t);
        }
    } catch (MetadataMismatchException e) {
        // Good actually, or?
        assertThat(e.getMessage(), containsString("format version"));
        fsRule.get().deleteFile(storeFile);
        createAndZipTree(storeFile);
        tellDeveloperToCommitThisFormatVersion();
    }
}
Also used : FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) MutableLong(org.apache.commons.lang3.mutable.MutableLong) ZipFile(java.util.zip.ZipFile) File(java.io.File) PageCache(org.neo4j.io.pagecache.PageCache) Test(org.junit.Test)

Example 24 with MutableLong

use of org.apache.commons.lang3.mutable.MutableLong in project neo4j by neo4j.

the class FormatCompatibilityTest method createAndZipTree.

private void createAndZipTree(File storeFile) throws IOException {
    PageCache pageCache = pageCacheRule.getPageCache(fsRule.get());
    try (GBPTree<MutableLong, MutableLong> tree = new GBPTree<>(pageCache, storeFile, new SimpleLongLayout(), 0, NO_MONITOR, NO_HEADER)) {
        MutableLong insertKey = new MutableLong();
        MutableLong insertValue = new MutableLong();
        int batchSize = KEY_COUNT / 10;
        for (int i = 0, key = 0; i < 10; i++) {
            try (Writer<MutableLong, MutableLong> writer = tree.writer()) {
                for (int j = 0; j < batchSize; j++, key++) {
                    insertKey.setValue(key);
                    insertValue.setValue(value(key));
                    writer.put(insertKey, insertValue);
                }
            }
            tree.checkpoint(IOLimiter.unlimited());
        }
    }
    zip(storeFile);
}
Also used : MutableLong(org.apache.commons.lang3.mutable.MutableLong) PageCache(org.neo4j.io.pagecache.PageCache)

Example 25 with MutableLong

use of org.apache.commons.lang3.mutable.MutableLong in project neo4j by neo4j.

the class GBPTreeRecoveryTest method doShouldRecoverFromAnything.

private void doShouldRecoverFromAnything(boolean replayRecoveryExactlyFromCheckpoint) throws Exception {
    assertInitialized();
    // GIVEN
    // a tree which has had random updates and checkpoints in it, load generated with specific seed
    File file = directory.file("index");
    List<Action> load = generateLoad();
    int lastCheckPointIndex = indexOfLastCheckpoint(load);
    {
        // _,_,_,_,_,_,_,c,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,c,_,_,_,_,_,_,_,_,_,_,_
        //                                                 ^             ^
        //                                                 |             |------------ crash flush index
        //                                                 |-------------------------- last checkpoint index
        //
        PageCache pageCache = createPageCache();
        GBPTree<MutableLong, MutableLong> index = createIndex(pageCache, file);
        // Execute all actions up to and including last checkpoint ...
        execute(load.subList(0, lastCheckPointIndex + 1), index);
        // ... a random amount of the remaining "unsafe" actions ...
        int numberOfRemainingActions = load.size() - lastCheckPointIndex - 1;
        int crashFlushIndex = lastCheckPointIndex + random.nextInt(numberOfRemainingActions) + 1;
        execute(load.subList(lastCheckPointIndex + 1, crashFlushIndex), index);
        // ... flush ...
        pageCache.flushAndForce();
        // ... execute the remaining actions
        execute(load.subList(crashFlushIndex, load.size()), index);
        // ... and finally crash
        fs.snapshot(throwing(() -> {
            index.close();
            pageCache.close();
        }));
    }
    // WHEN doing recovery
    List<Action> recoveryActions;
    if (replayRecoveryExactlyFromCheckpoint) {
        recoveryActions = recoveryActions(load, lastCheckPointIndex + 1);
    } else {
        recoveryActions = recoveryActions(load, random.nextInt(lastCheckPointIndex + 1));
    }
    // first crashing during recovery
    int numberOfCrashesDuringRecovery = random.intBetween(0, 3);
    for (int i = 0; i < numberOfCrashesDuringRecovery; i++) {
        PageCache pageCache = createPageCache();
        GBPTree<MutableLong, MutableLong> index = createIndex(pageCache, file);
        int numberOfActionsToRecoverBeforeCrashing = random.intBetween(1, recoveryActions.size());
        recover(recoveryActions.subList(0, numberOfActionsToRecoverBeforeCrashing), index);
        pageCache.flushAndForce();
        fs.snapshot(throwing(() -> {
            index.close();
            pageCache.close();
        }));
    }
    // to finally apply all actions after last checkpoint and verify tree
    try (PageCache pageCache = createPageCache();
        GBPTree<MutableLong, MutableLong> index = createIndex(pageCache, file)) {
        recover(recoveryActions, index);
        index.finishRecovery();
        // THEN
        // we should end up with a consistent index containing all the stuff load says
        index.consistencyCheck();
        long[] /*key,value,key,value...*/
        aggregate = expectedSortedAggregatedDataFromGeneratedLoad(load);
        try (RawCursor<Hit<MutableLong, MutableLong>, IOException> cursor = index.seek(new MutableLong(Long.MIN_VALUE), new MutableLong(Long.MAX_VALUE))) {
            for (int i = 0; i < aggregate.length; ) {
                assertTrue(cursor.next());
                Hit<MutableLong, MutableLong> hit = cursor.get();
                assertEquals(aggregate[i++], hit.key().longValue());
                assertEquals(aggregate[i++], hit.value().longValue());
            }
            assertFalse(cursor.next());
        }
    }
}
Also used : IOException(java.io.IOException) MutableLong(org.apache.commons.lang3.mutable.MutableLong) File(java.io.File) PageCache(org.neo4j.io.pagecache.PageCache)

Aggregations

MutableLong (org.apache.commons.lang3.mutable.MutableLong)42 Test (org.junit.Test)33 IOException (java.io.IOException)10 PageCache (org.neo4j.io.pagecache.PageCache)4 File (java.io.File)3 MutableBoolean (org.apache.commons.lang3.mutable.MutableBoolean)3 PageCursor (org.neo4j.io.pagecache.PageCursor)3 FileNotFoundException (java.io.FileNotFoundException)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 Random (java.util.Random)1 TreeMap (java.util.TreeMap)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 ZipFile (java.util.zip.ZipFile)1 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)1 PrimitiveLongSet (org.neo4j.collection.primitive.PrimitiveLongSet)1 CursorException (org.neo4j.io.pagecache.CursorException)1 DelegatingPageCursor (org.neo4j.io.pagecache.impl.DelegatingPageCursor)1 Randoms (org.neo4j.test.Randoms)1 Group (org.neo4j.unsafe.impl.batchimport.input.Group)1