Search in sources :

Example 6 with Entry

use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.

the class HadoopScanMapper method findEntriesMatchingQuery.

private EntryList findEntriesMatchingQuery(SliceQuery query, EntryList sortedEntries) {
    // Inclusive
    int lowestStartMatch = sortedEntries.size();
    // Inclusive
    int highestEndMatch = -1;
    final StaticBuffer queryStart = query.getSliceStart();
    final StaticBuffer queryEnd = query.getSliceEnd();
    // Find the lowest matchStart s.t. query.getSliceStart <= sortedEntries.get(matchStart)
    int low = 0;
    int high = sortedEntries.size() - 1;
    while (low <= high) {
        int mid = (low + high) >>> 1;
        Entry midVal = sortedEntries.get(mid);
        int cmpStart = queryStart.compareTo(midVal.getColumn());
        if (0 < cmpStart) {
            // query lower bound exceeds entry (no match)
            if (lowestStartMatch == mid + 1) {
                // lowestStartMatch located
                break;
            }
            // Move to higher list index
            low = mid + 1;
        } else /* (0 >= cmpStart) */
        {
            // entry equals or exceeds query lower bound (match, but not necessarily lowest match)
            if (mid < lowestStartMatch) {
                lowestStartMatch = mid;
            }
            // Move to a lower list index
            high = mid - 1;
        }
    }
    // so we can bypass the highestEndMatch search and just return an empty result.
    if (sortedEntries.size() == lowestStartMatch) {
        return EntryList.EMPTY_LIST;
    }
    // Find the highest matchEnd s.t. sortedEntries.get(matchEnd) < query.getSliceEnd
    low = 0;
    high = sortedEntries.size() - 1;
    while (low <= high) {
        int mid = (low + high) >>> 1;
        Entry midVal = sortedEntries.get(mid);
        int cmpEnd = queryEnd.compareTo(midVal.getColumn());
        if (0 < cmpEnd) {
            // query upper bound exceeds entry (match, not necessarily highest)
            if (mid > highestEndMatch) {
                highestEndMatch = mid;
            }
            // Move to higher list index
            low = mid + 1;
        } else /* (0 >= cmpEnd) */
        {
            // entry equals or exceeds query upper bound (no match)
            if (highestEndMatch == mid - 1) {
                // highestEndMatch located
                break;
            }
            // Move to a lower list index
            high = mid - 1;
        }
    }
    if (0 <= highestEndMatch - lowestStartMatch) {
        // Return sublist between indices (inclusive at both indices)
        // This will be passed into subList, which interprets it exclusively
        int endIndex = highestEndMatch + 1;
        if (query.hasLimit()) {
            endIndex = Math.min(endIndex, query.getLimit() + lowestStartMatch);
        }
        // TODO avoid unnecessary copy here
        return EntryArrayList.of(sortedEntries.subList(lowestStartMatch, endIndex));
    } else {
        return EntryList.EMPTY_LIST;
    }
}
Also used : Entry(org.janusgraph.diskstorage.Entry) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer)

Example 7 with Entry

use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.

the class SimpleVertexQueryProcessor method vertexIds.

/**
 * Returns the list of adjacent vertex ids for this query. By reading those ids
 * from the entries directly (without creating objects) we get much better performance.
 *
 * @return
 */
public VertexList vertexIds() {
    LongArrayList list = new LongArrayList();
    long previousId = 0;
    for (Long id : Iterables.transform(this, new Function<Entry, Long>() {

        @Nullable
        @Override
        public Long apply(@Nullable Entry entry) {
            return edgeSerializer.readRelation(entry, true, tx).getOtherVertexId();
        }
    })) {
        list.add(id);
        if (id >= previousId && previousId >= 0)
            previousId = id;
        else
            previousId = -1;
    }
    return new VertexLongList(tx, list, previousId >= 0);
}
Also used : Entry(org.janusgraph.diskstorage.Entry) LongArrayList(com.carrotsearch.hppc.LongArrayList) Nullable(javax.annotation.Nullable)

Example 8 with Entry

use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.

the class IndexRepairJob method process.

@Override
public void process(JanusGraphVertex vertex, ScanMetrics metrics) {
    try {
        BackendTransaction mutator = writeTx.getTxHandle();
        if (index instanceof RelationTypeIndex) {
            RelationTypeIndexWrapper wrapper = (RelationTypeIndexWrapper) index;
            InternalRelationType wrappedType = wrapper.getWrappedType();
            EdgeSerializer edgeSerializer = writeTx.getEdgeSerializer();
            List<Entry> additions = new ArrayList<>();
            for (Object relation : vertex.query().types(indexRelationTypeName).direction(Direction.OUT).relations()) {
                InternalRelation janusgraphRelation = (InternalRelation) relation;
                for (int pos = 0; pos < janusgraphRelation.getArity(); pos++) {
                    if (!wrappedType.isUnidirected(Direction.BOTH) && !wrappedType.isUnidirected(EdgeDirection.fromPosition(pos)))
                        // Directionality is not covered
                        continue;
                    Entry entry = edgeSerializer.writeRelation(janusgraphRelation, wrappedType, pos, writeTx);
                    additions.add(entry);
                }
            }
            StaticBuffer vertexKey = writeTx.getIdInspector().getKey(vertex.longId());
            mutator.mutateEdges(vertexKey, additions, KCVSCache.NO_DELETIONS);
            metrics.incrementCustom(ADDED_RECORDS_COUNT, additions.size());
        } else if (index instanceof JanusGraphIndex) {
            IndexType indexType = managementSystem.getSchemaVertex(index).asIndexType();
            assert indexType != null;
            IndexSerializer indexSerializer = graph.getIndexSerializer();
            // Gather elements to index
            List<JanusGraphElement> elements;
            switch(indexType.getElement()) {
                case VERTEX:
                    elements = ImmutableList.of(vertex);
                    break;
                case PROPERTY:
                    elements = Lists.newArrayList();
                    for (JanusGraphVertexProperty p : addIndexSchemaConstraint(vertex.query(), indexType).properties()) {
                        elements.add(p);
                    }
                    break;
                case EDGE:
                    elements = Lists.newArrayList();
                    for (Object e : addIndexSchemaConstraint(vertex.query().direction(Direction.OUT), indexType).edges()) {
                        elements.add((JanusGraphEdge) e);
                    }
                    break;
                default:
                    throw new AssertionError("Unexpected category: " + indexType.getElement());
            }
            if (indexType.isCompositeIndex()) {
                for (JanusGraphElement element : elements) {
                    Set<IndexSerializer.IndexUpdate<StaticBuffer, Entry>> updates = indexSerializer.reindexElement(element, (CompositeIndexType) indexType);
                    for (IndexSerializer.IndexUpdate<StaticBuffer, Entry> update : updates) {
                        log.debug("Mutating index {}: {}", indexType, update.getEntry());
                        mutator.mutateIndex(update.getKey(), Lists.newArrayList(update.getEntry()), KCVSCache.NO_DELETIONS);
                        metrics.incrementCustom(ADDED_RECORDS_COUNT);
                    }
                }
            } else {
                assert indexType.isMixedIndex();
                Map<String, Map<String, List<IndexEntry>>> documentsPerStore = new HashMap<>();
                for (JanusGraphElement element : elements) {
                    indexSerializer.reindexElement(element, (MixedIndexType) indexType, documentsPerStore);
                    metrics.incrementCustom(DOCUMENT_UPDATES_COUNT);
                }
                mutator.getIndexTransaction(indexType.getBackingIndexName()).restore(documentsPerStore);
            }
        } else
            throw new UnsupportedOperationException("Unsupported index found: " + index);
    } catch (final Exception e) {
        managementSystem.rollback();
        writeTx.rollback();
        metrics.incrementCustom(FAILED_TX);
        throw new JanusGraphException(e.getMessage(), e);
    }
}
Also used : InternalRelation(org.janusgraph.graphdb.internal.InternalRelation) IndexEntry(org.janusgraph.diskstorage.indexing.IndexEntry) Entry(org.janusgraph.diskstorage.Entry) EdgeSerializer(org.janusgraph.graphdb.database.EdgeSerializer) RelationTypeIndexWrapper(org.janusgraph.graphdb.database.management.RelationTypeIndexWrapper) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer) ImmutableList(com.google.common.collect.ImmutableList) MixedIndexType(org.janusgraph.graphdb.types.MixedIndexType) IndexType(org.janusgraph.graphdb.types.IndexType) CompositeIndexType(org.janusgraph.graphdb.types.CompositeIndexType) BackendTransaction(org.janusgraph.diskstorage.BackendTransaction) MixedIndexType(org.janusgraph.graphdb.types.MixedIndexType) IndexSerializer(org.janusgraph.graphdb.database.IndexSerializer) CompositeIndexType(org.janusgraph.graphdb.types.CompositeIndexType) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType)

Example 9 with Entry

use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.

the class CQLResultSetKeyIteratorTest method testIterator.

@Test
public void testIterator() throws IOException {
    final Array<Row> rows = Array.rangeClosed(1, 100).map(idx -> {
        final Row row = mock(Row.class);
        when(row.getBytes("key")).thenReturn(ByteBuffer.wrap(Integer.toString(idx / 5).getBytes()));
        when(row.getBytes("column1")).thenReturn(ByteBuffer.wrap(Integer.toString(idx % 5).getBytes()));
        when(row.getBytes("value")).thenReturn(ByteBuffer.wrap(Integer.toString(idx).getBytes()));
        return row;
    });
    final ResultSet resultSet = mock(ResultSet.class);
    when(resultSet.iterator()).thenReturn(rows.iterator());
    final CQLColValGetter getter = new CQLColValGetter(new EntryMetaData[0]);
    try (final CQLResultSetKeyIterator resultSetKeyIterator = new CQLResultSetKeyIterator(ALL_COLUMNS, getter, resultSet)) {
        int i = 0;
        while (resultSetKeyIterator.hasNext()) {
            final StaticBuffer next = resultSetKeyIterator.next();
            final RecordIterator<Entry> entries = resultSetKeyIterator.getEntries();
            while (entries.hasNext()) {
                final Row row = rows.get(i++);
                final Entry entry = entries.next();
                assertEquals(row.getBytes("key"), next.asByteBuffer());
                assertEquals(row.getBytes("column1"), entry.getColumn().asByteBuffer());
                assertEquals(row.getBytes("value"), entry.getValue().asByteBuffer());
            }
        }
    }
}
Also used : Entry(org.janusgraph.diskstorage.Entry) ResultSet(com.datastax.driver.core.ResultSet) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer) Row(com.datastax.driver.core.Row) Test(org.junit.Test)

Example 10 with Entry

use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.

the class CQLResultSetKeyIteratorTest method testPartialIterateColumns.

@Test
public void testPartialIterateColumns() throws IOException {
    final Random random = new Random();
    final Function1<Integer, ByteBuffer> randomLong = idx -> {
        final ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES).putLong(random.nextLong());
        buffer.flip();
        return buffer;
    };
    final Array<Tuple2<ByteBuffer, Array<Tuple2<ByteBuffer, ByteBuffer>>>> keysMap = Array.range(0, random.nextInt(100) + 100).map(randomLong).map(key -> Tuple.of(key, Array.rangeClosed(0, random.nextInt(100) + 1).map(idx -> Tuple.of(randomLong.apply(idx), randomLong.apply(idx)))));
    final Seq<Row> rows = keysMap.flatMap(tuple -> tuple._2.map(columnAndValue -> {
        final Row row = mock(Row.class);
        when(row.getBytes("key")).thenReturn(tuple._1);
        when(row.getBytes("column1")).thenReturn(columnAndValue._1);
        when(row.getBytes("value")).thenReturn(columnAndValue._2);
        return row;
    }));
    final ResultSet resultSet = mock(ResultSet.class);
    when(resultSet.iterator()).thenReturn(rows.iterator());
    final CQLColValGetter getter = new CQLColValGetter(new EntryMetaData[0]);
    try (final CQLResultSetKeyIterator resultSetKeyIterator = new CQLResultSetKeyIterator(ALL_COLUMNS, getter, resultSet)) {
        final Iterator<Tuple2<ByteBuffer, Array<Tuple2<ByteBuffer, ByteBuffer>>>> iterator = keysMap.iterator();
        while (resultSetKeyIterator.hasNext()) {
            final StaticBuffer next = resultSetKeyIterator.next();
            try (final RecordIterator<Entry> entries = resultSetKeyIterator.getEntries()) {
                final Tuple2<ByteBuffer, Array<Tuple2<ByteBuffer, ByteBuffer>>> current = iterator.next();
                final ByteBuffer currentKey = current._1;
                final Array<Tuple2<ByteBuffer, ByteBuffer>> columnValues = current._2;
                final Iterator<Tuple2<ByteBuffer, ByteBuffer>> columnIterator = columnValues.iterator();
                while (entries.hasNext()) {
                    final Entry entry = entries.next();
                    final Tuple2<ByteBuffer, ByteBuffer> columnAndValue = columnIterator.next();
                    assertEquals(currentKey, next.asByteBuffer());
                    assertEquals(columnAndValue._1, entry.getColumn().asByteBuffer());
                    assertEquals(columnAndValue._2, entry.getValue().asByteBuffer());
                    assertEquals(columnIterator.hasNext(), entries.hasNext());
                    // 10% of the time, don't complete the iteration
                    if (random.nextInt(10) == 0) {
                        break;
                    }
                }
            }
        }
    }
}
Also used : Tuple(io.vavr.Tuple) EntryMetaData(org.janusgraph.diskstorage.EntryMetaData) Row(com.datastax.driver.core.Row) SliceQuery(org.janusgraph.diskstorage.keycolumnvalue.SliceQuery) Array(io.vavr.collection.Array) IOException(java.io.IOException) Random(java.util.Random) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) Function1(io.vavr.Function1) ByteBuffer(java.nio.ByteBuffer) RecordIterator(org.janusgraph.diskstorage.util.RecordIterator) ResultSet(com.datastax.driver.core.ResultSet) Tuple2(io.vavr.Tuple2) Assert.assertFalse(org.junit.Assert.assertFalse) Entry(org.janusgraph.diskstorage.Entry) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer) BufferUtil(org.janusgraph.diskstorage.util.BufferUtil) Iterator(io.vavr.collection.Iterator) Seq(io.vavr.collection.Seq) Assert.assertEquals(org.junit.Assert.assertEquals) Mockito.mock(org.mockito.Mockito.mock) ByteBuffer(java.nio.ByteBuffer) Array(io.vavr.collection.Array) Entry(org.janusgraph.diskstorage.Entry) Random(java.util.Random) Tuple2(io.vavr.Tuple2) ResultSet(com.datastax.driver.core.ResultSet) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer) Row(com.datastax.driver.core.Row) Test(org.junit.Test)

Aggregations

Entry (org.janusgraph.diskstorage.Entry)24 StaticBuffer (org.janusgraph.diskstorage.StaticBuffer)13 Test (org.junit.Test)8 ArrayList (java.util.ArrayList)6 Map (java.util.Map)5 StaticArrayEntry (org.janusgraph.diskstorage.util.StaticArrayEntry)5 ByteBuffer (java.nio.ByteBuffer)4 HashMap (java.util.HashMap)4 ResultSet (com.datastax.driver.core.ResultSet)3 Row (com.datastax.driver.core.Row)3 ImmutableList (com.google.common.collect.ImmutableList)3 ImmutableMap (com.google.common.collect.ImmutableMap)3 Instant (java.time.Instant)3 List (java.util.List)3 EntryList (org.janusgraph.diskstorage.EntryList)3 Function1 (io.vavr.Function1)2 Tuple (io.vavr.Tuple)2 Tuple2 (io.vavr.Tuple2)2 Array (io.vavr.collection.Array)2 Iterator (io.vavr.collection.Iterator)2