Java Code Examples for org.apache.tinkerpop.gremlin.process.computer.Memory#get()

The following examples show how to use org.apache.tinkerpop.gremlin.process.computer.Memory#get() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ProgramTest.java    From tinkerpop with Apache License 2.0 6 votes vote down vote up
@Override
public boolean terminate(final Memory memory) {
    final TraverserGenerator generator = this.traversal.get().getTraverserGenerator();
    MemoryTraversalSideEffects.setMemorySideEffects(this.traversal.get(), memory, ProgramPhase.TERMINATE);
    checkSideEffects();
    if (memory.isInitialIteration()) {
        assertFalse(memory.exists(TraversalVertexProgram.HALTED_TRAVERSERS));
        return false;
    } else {
        ///
        assertTrue(memory.exists(TraversalVertexProgram.HALTED_TRAVERSERS));
        final TraverserSet<String> haltedTraversers = memory.get(TraversalVertexProgram.HALTED_TRAVERSERS);
        haltedTraversers.add(generator.generate("hello", this.programStep, 1l));
        haltedTraversers.add(generator.generate("gremlin", this.programStep, 1l));
        memory.set(TraversalVertexProgram.HALTED_TRAVERSERS, haltedTraversers);
        return true;
    }
}
 
Example 2
Source File: ConnectedComponentVertexProgramStep.java    From tinkerpop with Apache License 2.0 6 votes vote down vote up
@Override
public ConnectedComponentVertexProgram generateProgram(final Graph graph, final Memory memory) {
    final Traversal.Admin<Vertex, Edge> detachedTraversal = this.edgeTraversal.getPure();
    detachedTraversal.setStrategies(TraversalStrategies.GlobalCache.getStrategies(graph.getClass()));

    final ConnectedComponentVertexProgram.Builder builder = ConnectedComponentVertexProgram.build().
            edges(detachedTraversal).
            property(this.clusterProperty);

    if (memory.exists(TraversalVertexProgram.HALTED_TRAVERSERS)) {
        final TraverserSet<?> haltedTraversers = memory.get(TraversalVertexProgram.HALTED_TRAVERSERS);
        if (!haltedTraversers.isEmpty()) {
            Object haltedTraversersValue;
            try {
                haltedTraversersValue = Base64.getEncoder().encodeToString(Serializer.serializeObject(haltedTraversers));
            } catch (final IOException ignored) {
                haltedTraversersValue = haltedTraversers;
            }
            builder.configure(TraversalVertexProgram.HALTED_TRAVERSERS, haltedTraversersValue);
        }
    }

    return builder.create(graph);
}
 
Example 3
Source File: ShortestPathVertexProgram.java    From tinkerpop with Apache License 2.0 6 votes vote down vote up
private void updateHaltedTraversers(final Vertex vertex, final Memory memory) {
    if (isStartVertex(vertex)) {
        final List<Path> paths = memory.get(SHORTEST_PATHS);
        if (vertex.property(TraversalVertexProgram.HALTED_TRAVERSERS).isPresent()) {
            // replace the current set of halted traversers with new new traversers that hold the shortest paths
            // found for this vertex
            final TraverserSet<Vertex> haltedTraversers = vertex.value(TraversalVertexProgram.HALTED_TRAVERSERS);
            final TraverserSet<Path> newHaltedTraversers = new TraverserSet<>();
            for (final Traverser.Admin<Vertex> traverser : haltedTraversers) {
                final Vertex v = traverser.get();
                for (final Path path : paths) {
                    if (path.get(0).equals(v)) {
                        newHaltedTraversers.add(traverser.split(path, this.programStep));
                    }
                }
            }
            vertex.property(VertexProperty.Cardinality.single, TraversalVertexProgram.HALTED_TRAVERSERS, newHaltedTraversers);
        }
    }
}
 
Example 4
Source File: ShortestPathVertexProgram.java    From tinkerpop with Apache License 2.0 6 votes vote down vote up
@Override
public boolean terminate(final Memory memory) {
    if (memory.isInitialIteration() && this.haltedTraversersIndex != null) {
        this.haltedTraversersIndex.clear();
    }
    final boolean voteToHalt = memory.get(VOTE_TO_HALT);
    if (voteToHalt) {
        final int state = memory.get(STATE);
        if (state == COLLECT_PATHS) {
            // After paths were collected,
            // a) the VP is done in standalone mode (paths will be in memory) or
            // b) the halted traversers will be updated in order to have the paths available in the traversal
            if (this.standalone) return true;
            memory.set(STATE, UPDATE_HALTED_TRAVERSERS);
            return false;
        }
        if (state == UPDATE_HALTED_TRAVERSERS) return true;
        else memory.set(STATE, COLLECT_PATHS); // collect paths if no new paths were found
        return false;
    } else {
        memory.set(VOTE_TO_HALT, true);
        return false;
    }
}
 
Example 5
Source File: KCoreVertexProgram.java    From grakn with GNU Affero General Public License v3.0 6 votes vote down vote up
static void filterByDegree(Vertex vertex, Messenger<String> messenger, Memory memory, boolean persistId) {
    if ((vertex.label().equals(Schema.BaseType.ENTITY.name()) ||
            vertex.label().equals(Schema.BaseType.ATTRIBUTE.name())) &&
            Iterators.size(messenger.receiveMessages()) >= memory.<Long>get(K)) {
        String id = vertex.id().toString();

        // coreness query doesn't require id
        if (persistId) {
            vertex.property(K_CORE_LABEL, id);
        } else {
            vertex.property(K_CORE_LABEL, true);
        }
        memory.add(K_CORE_EXIST, true);

        // send ids from now on, as we want to count connected entities, not relations
        sendMessage(messenger, id);
    }
}
 
Example 6
Source File: ConnectedComponentVertexProgram.java    From tinkerpop with Apache License 2.0 6 votes vote down vote up
@Override
public boolean terminate(final Memory memory) {
    if (memory.isInitialIteration() && this.haltedTraversersIndex != null) {
        this.haltedTraversersIndex.clear();
    }

    final boolean voteToHalt = memory.<Boolean>get(VOTE_TO_HALT);
    if (voteToHalt) {
        return true;
    } else {
        // it is basically always assumed that the program will want to halt, but if message passing occurs, the
        // program will want to continue, thus reset false values to true for future iterations
        memory.set(VOTE_TO_HALT, true);
        return false;
    }
}
 
Example 7
Source File: ProgramTest.java    From tinkerpop with Apache License 2.0 5 votes vote down vote up
@Override
public void execute(final Vertex vertex, final Messenger messenger, final Memory memory) {
    assertFalse(memory.exists(TraversalVertexProgram.HALTED_TRAVERSERS));
    final TraverserGenerator generator = this.traversal.get().getTraverserGenerator();
    MemoryTraversalSideEffects.setMemorySideEffects(this.traversal.get(), memory, ProgramPhase.EXECUTE);
    this.checkSideEffects();
    final TraverserSet<Vertex> activeTraversers = memory.get(TraversalVertexProgram.ACTIVE_TRAVERSERS);
    if (vertex.label().equals("software")) {
        assertEquals(1, activeTraversers.stream().filter(v -> v.get().equals(vertex)).count());
        if (memory.isInitialIteration()) {
            assertFalse(vertex.property(TraversalVertexProgram.HALTED_TRAVERSERS).isPresent());
            vertex.property(
                    TraversalVertexProgram.HALTED_TRAVERSERS,
                    new TraverserSet<>(generator.generate(vertex.value("name"), this.programStep, 1l)));
        } else {
            assertTrue(vertex.property(TraversalVertexProgram.HALTED_TRAVERSERS).isPresent());
        }
    } else {
        assertFalse(vertex.property(TraversalVertexProgram.HALTED_TRAVERSERS).isPresent());
        assertEquals(0, activeTraversers.stream().filter(v -> v.get().equals(vertex)).count());
        if (!memory.isInitialIteration()) {
            if (vertex.value("name").equals("marko"))
                memory.add(TraversalVertexProgram.HALTED_TRAVERSERS, new TraverserSet<>(generator.generate("marko-is-my-name", this.programStep, 1l)));
            else if (vertex.value("name").equals("vadas"))
                this.traversal.get().getSideEffects().add(TraversalVertexProgram.HALTED_TRAVERSERS, new TraverserSet<>(generator.generate("the-v-o-double-g", this.programStep, 1l)));
        }
    }
}
 
Example 8
Source File: PeerPressureVertexProgram.java    From tinkerpop with Apache License 2.0 5 votes vote down vote up
@Override
public boolean terminate(final Memory memory) {
    final boolean voteToHalt = memory.<Boolean>get(VOTE_TO_HALT) || memory.getIteration() >= (this.distributeVote ? this.maxIterations + 1 : this.maxIterations);
    if (voteToHalt) {
        return true;
    } else {
        memory.set(VOTE_TO_HALT, true);
        return false;
    }
}
 
Example 9
Source File: PageRankVertexProgram.java    From tinkerpop with Apache License 2.0 5 votes vote down vote up
@Override
public void execute(final Vertex vertex, Messenger<Double> messenger, final Memory memory) {
    if (memory.isInitialIteration()) {
        messenger.sendMessage(this.countMessageScope, 1.0d);
        memory.add(VERTEX_COUNT, 1.0d);
    } else {
        final double vertexCount = memory.<Double>get(VERTEX_COUNT);
        final double edgeCount;
        double pageRank;
        if (1 == memory.getIteration()) {
            edgeCount = IteratorUtils.reduce(messenger.receiveMessages(), 0.0d, (a, b) -> a + b);
            vertex.property(VertexProperty.Cardinality.single, EDGE_COUNT, edgeCount);
            pageRank = null == this.initialRankTraversal ?
                    0.0d :
                    TraversalUtil.apply(vertex, this.initialRankTraversal.get()).doubleValue();
        } else {
            edgeCount = vertex.value(EDGE_COUNT);
            pageRank = IteratorUtils.reduce(messenger.receiveMessages(), 0.0d, (a, b) -> a + b);
        }
        //////////////////////////
        final double teleporationEnergy = memory.get(TELEPORTATION_ENERGY);
        if (teleporationEnergy > 0.0d) {
            final double localTerminalEnergy = teleporationEnergy / vertexCount;
            pageRank = pageRank + localTerminalEnergy;
            memory.add(TELEPORTATION_ENERGY, -localTerminalEnergy);
        }
        final double previousPageRank = vertex.<Double>property(this.property).orElse(0.0d);
        memory.add(CONVERGENCE_ERROR, Math.abs(pageRank - previousPageRank));
        vertex.property(VertexProperty.Cardinality.single, this.property, pageRank);
        memory.add(TELEPORTATION_ENERGY, (1.0d - this.alpha) * pageRank);
        pageRank = this.alpha * pageRank;
        if (edgeCount > 0.0d)
            messenger.sendMessage(this.incidentMessageScope, pageRank / edgeCount);
        else
            memory.add(TELEPORTATION_ENERGY, pageRank);
    }
}
 
Example 10
Source File: ConnectedComponentsVertexProgram.java    From grakn with GNU Affero General Public License v3.0 5 votes vote down vote up
@Override
public boolean terminate(final Memory memory) {
    LOGGER.debug("Finished Iteration {}", memory.getIteration());
    if (memory.getIteration() < 2) return false;
    if (memory.<Boolean>get(VOTE_TO_HALT)) {
        return true;
    }
    if (memory.getIteration() == MAX_ITERATION) {
        LOGGER.debug("Reached Max Iteration: {}", MAX_ITERATION);
        throw GraqlQueryException.maxIterationsReached(this.getClass());
    }

    memory.set(VOTE_TO_HALT, true);
    return false;
}
 
Example 11
Source File: ConnectedComponentVertexProgram.java    From grakn with GNU Affero General Public License v3.0 5 votes vote down vote up
@Override
public boolean terminate(final Memory memory) {
    LOGGER.debug("Finished Iteration " + memory.getIteration());
    if (memory.isInitialIteration()) return false;
    if (memory.<Boolean>get(VOTE_TO_HALT)) {
        return true;
    }
    if (memory.getIteration() == MAX_ITERATION) {
        LOGGER.debug("Reached Max Iteration: " + MAX_ITERATION + " !!!!!!!!");
        throw GraqlQueryException.maxIterationsReached(this.getClass());
    }

    memory.set(VOTE_TO_HALT, true);
    return false;
}
 
Example 12
Source File: KCoreVertexProgram.java    From grakn with GNU Affero General Public License v3.0 5 votes vote down vote up
@Override
public boolean terminate(final Memory memory) {
    LOGGER.debug("Finished Iteration {}", memory.getIteration());
    if (memory.isInitialIteration()) return false;

    if (memory.getIteration() == MAX_ITERATION) {
        LOGGER.debug("Reached Max Iteration: {}", MAX_ITERATION);
        throw GraqlQueryException.maxIterationsReached(this.getClass());
    }

    if (memory.<Boolean>get(CONNECTED_COMPONENT_STARTED)) {
        if (memory.<Boolean>get(VOTE_TO_HALT)) {
            LOGGER.debug("KCoreVertexProgram Finished");
            return true; // connected component is done
        } else {
            memory.set(VOTE_TO_HALT, true);
            return false;
        }
    } else {
        if (!atRelations(memory)) {
            if (!memory.<Boolean>get(K_CORE_EXIST)) {
                LOGGER.debug("KCoreVertexProgram Finished");
                LOGGER.debug("No Such Core Areas Found");
                throw new NoResultException();
            } else {
                if (memory.<Boolean>get(K_CORE_STABLE)) {
                    memory.set(CONNECTED_COMPONENT_STARTED, true);
                    LOGGER.debug("Found Core Areas");
                    LOGGER.debug("Starting Connected Components");
                } else {
                    memory.set(K_CORE_EXIST, false);
                    memory.set(K_CORE_STABLE, true);
                }
                return false;
            }
        } else {
            return false; // can not end after relayOrSaveMessages
        }
    }
}
 
Example 13
Source File: KCoreVertexProgram.java    From grakn with GNU Affero General Public License v3.0 5 votes vote down vote up
static void updateEntityAndAttribute(Vertex vertex, Messenger<String> messenger,
                                     Memory memory, boolean persistMessageCount) {
    if (vertex.property(K_CORE_LABEL).isPresent()) {
        String id = vertex.id().toString();
        long messageCount = (long) getMessageCountExcludeSelf(messenger, id);
        if (vertex.property(IMPLICIT_MESSAGE_COUNT).isPresent()) {
            messageCount += vertex.<Long>value(IMPLICIT_MESSAGE_COUNT);
            // need to remove implicit count as the vertex may not receive msg via implicit edge
            vertex.property(IMPLICIT_MESSAGE_COUNT).remove();
        }

        if (messageCount >= memory.<Long>get(K)) {
            LOGGER.trace("Sending msg from {}", id);
            sendMessage(messenger, id);
            memory.add(K_CORE_EXIST, true);

            if (persistMessageCount) {
                // message count may help eliminate unqualified vertex in earlier iterations
                vertex.property(MESSAGE_COUNT, messageCount);
            }
        } else {
            LOGGER.trace("Removing label of {}", id);
            vertex.property(K_CORE_LABEL).remove();
            memory.add(K_CORE_STABLE, false);
        }
    }
}
 
Example 14
Source File: KCoreVertexProgram.java    From grakn with GNU Affero General Public License v3.0 5 votes vote down vote up
@Override
public void safeExecute(final Vertex vertex, Messenger<String> messenger, final Memory memory) {
    switch (memory.getIteration()) {
        case 0:
            sendMessage(messenger, EMPTY_MESSAGE);
            break;

        case 1: // get degree first, as degree must >= k
            filterByDegree(vertex, messenger, memory, true);
            break;

        default:
            if (memory.<Boolean>get(CONNECTED_COMPONENT_STARTED)) {
                if (messenger.receiveMessages().hasNext()) {
                    if (vertex.property(K_CORE_LABEL).isPresent()) {
                        updateClusterLabel(vertex, messenger, memory);
                    } else if (vertex.label().equals(Schema.BaseType.RELATION.name())) {
                        relayClusterLabel(messenger, memory);
                    }
                }
            } else {
                // relay message through relation vertices in even iterations
                // send message from regular entities in odd iterations
                if (atRelations(memory)) {
                    relayOrSaveMessages(vertex, messenger);
                } else {
                    updateEntityAndAttribute(vertex, messenger, memory, false);
                }
            }
            break;
    }
}
 
Example 15
Source File: CorenessVertexProgram.java    From grakn with GNU Affero General Public License v3.0 5 votes vote down vote up
@Override
public boolean terminate(final Memory memory) {
    if (memory.isInitialIteration()) {
        LOGGER.debug("Finished Iteration {}", memory.getIteration());
        return false;
    }

    if (memory.getIteration() == MAX_ITERATION) {
        LOGGER.debug("Reached Max Iteration: {}", MAX_ITERATION);
        throw GraqlQueryException.maxIterationsReached(this.getClass());
    }

    if (memory.<Boolean>get(PERSIST_CORENESS)) {
        memory.set(PERSIST_CORENESS, false);
    }
    if (!atRelations(memory)) {
        LOGGER.debug("UpdateEntityAndAttribute... Finished Iteration {}", memory.getIteration());
        if (!memory.<Boolean>get(K_CORE_EXIST)) {
            LOGGER.debug("KCoreVertexProgram Finished");
            return true;
        } else {
            if (memory.<Boolean>get(K_CORE_STABLE)) {
                LOGGER.debug("Found Core Areas K = {}\n", memory.<Long>get(K));
                memory.set(K, memory.<Long>get(K) + 1L);
                memory.set(PERSIST_CORENESS, true);
            } else {
                memory.set(K_CORE_STABLE, true);
            }
            memory.set(K_CORE_EXIST, false);
            return false;
        }
    } else {
        LOGGER.debug("RelayOrSaveMessage...       Finished Iteration {}", memory.getIteration());
        return false; // can not end after relayOrSaveMessages
    }
}
 
Example 16
Source File: CorenessVertexProgram.java    From grakn with GNU Affero General Public License v3.0 5 votes vote down vote up
@Override
public void safeExecute(final Vertex vertex, Messenger<String> messenger, final Memory memory) {
    switch (memory.getIteration()) {
        case 0:
            sendMessage(messenger, EMPTY_MESSAGE);
            break;

        case 1: // get degree first, as degree must >= k
            filterByDegree(vertex, messenger, memory, false);
            break;

        default:
            if (memory.<Boolean>get(PERSIST_CORENESS) && vertex.property(K_CORE_LABEL).isPresent()) {
                // persist coreness
                vertex.property(CORENESS, memory.<Long>get(K) - 1L);

                // check if the vertex should included for the next k value
                if (vertex.<Long>value(MESSAGE_COUNT) < memory.<Long>get(K)) {
                    vertex.property(K_CORE_LABEL).remove();
                    break;
                }
            }

            // relay message through relation vertices in even iterations
            // send message from regular entities in odd iterations
            if (atRelations(memory)) {
                relayOrSaveMessages(vertex, messenger);
            } else {
                updateEntityAndAttribute(vertex, messenger, memory, true);
            }
            break;
    }
}
 
Example 17
Source File: ComputeExecutorImpl.java    From grakn with GNU Affero General Public License v3.0 4 votes vote down vote up
private Stream<ConceptSet> runComputeConnectedComponent(GraqlCompute.Cluster query) {
        boolean restrictSize = query.where().size().isPresent();

        if (!scopeContainsInstance(query)) {
            LOG.info("Selected types don't have instances");
            return Stream.empty();
        }

        Set<LabelId> scopeTypeLabelIDs = convertLabelsToIds(scopeTypeLabels(query));

        GraknVertexProgram<?> vertexProgram;
        if (query.where().contains().isPresent()) {
            ConceptId conceptId = ConceptId.of(query.where().contains().get());
            if (!scopeContainsInstances(query, conceptId)) {
                throw GraqlSemanticException.instanceDoesNotExist();
            }
            vertexProgram = new ConnectedComponentVertexProgram(conceptId);
        } else {
            vertexProgram = new ConnectedComponentsVertexProgram();
        }

        GraknMapReduce<?> mapReduce;
        if (restrictSize) {
            mapReduce = new ClusterMemberMapReduce(ConnectedComponentsVertexProgram.CLUSTER_LABEL, query.where().size().get());
        }
        else mapReduce = new ClusterMemberMapReduce(ConnectedComponentsVertexProgram.CLUSTER_LABEL);

        Memory memory = compute(vertexProgram, mapReduce, scopeTypeLabelIDs).memory();
        Map<String, Set<ConceptId>> result = memory.get(mapReduce.getClass().getName());
        return result.values().stream().map(ConceptSet::new);

//        TODO: Enable the following compute cluster-size through a separate compute method
//        if (!query.where().members().get()) {
//            GraknMapReduce<?> mapReduce;
//            if (restrictSize) {
//                mapreduce = new ClusterSizeMapReduce(ConnectedComponentsVertexProgram.CLUSTER_LABEL, query.where().size().get());
//            } else {
//                mapReduce = new ClusterSizeMapReduce(ConnectedComponentsVertexProgram.CLUSTER_LABEL);
//            }
//            Map<String, Long> result = memory.get(mapReduce.getClass().getName());
//            return result.values().stream().map(Value::new);
//        }
    }
 
Example 18
Source File: TraversalVertexProgram.java    From tinkerpop with Apache License 2.0 4 votes vote down vote up
@Override
public boolean terminate(final Memory memory) {
    // memory is local
    MemoryTraversalSideEffects.setMemorySideEffects(this.traversal.get(), memory, ProgramPhase.TERMINATE);
    final boolean voteToHalt = memory.<Boolean>get(VOTE_TO_HALT);
    memory.set(VOTE_TO_HALT, true);
    memory.set(ACTIVE_TRAVERSERS, new IndexedTraverserSet.VertexIndexedTraverserSet());
    if (voteToHalt) {
        // local traverser sets to process
        final TraverserSet<Object> toProcessTraversers = new TraverserSet<>();
        // traversers that need to be sent back to the workers (no longer can be processed locally by the master traversal)
        final IndexedTraverserSet<Object,Vertex> remoteActiveTraversers = new IndexedTraverserSet.VertexIndexedTraverserSet();
        // halted traversers that have completed their journey
        final TraverserSet<Object> haltedTraversers = memory.get(HALTED_TRAVERSERS);
        // get all barrier traversers
        final Set<String> completedBarriers = new HashSet<>();
        MasterExecutor.processMemory(this.traversalMatrix, memory, toProcessTraversers, completedBarriers);
        // process all results from barriers locally and when elements are touched, put them in remoteActiveTraversers
        MasterExecutor.processTraversers(this.traversal, this.traversalMatrix, toProcessTraversers, remoteActiveTraversers, haltedTraversers, this.haltedTraverserStrategy);
        // tell parallel barriers that might not have been active in the last round that they are no longer active
        memory.set(COMPLETED_BARRIERS, completedBarriers);
        if (!remoteActiveTraversers.isEmpty() ||
                completedBarriers.stream().map(this.traversalMatrix::getStepById).filter(step -> step instanceof LocalBarrier).findAny().isPresent()) {
            // send active traversers back to workers
            memory.set(ACTIVE_TRAVERSERS, remoteActiveTraversers);
            return false;
        } else {
            // finalize locally with any last traversers dangling in the local traversal
            final Step<?, Object> endStep = (Step<?, Object>) this.traversal.get().getEndStep();
            while (endStep.hasNext()) {
                haltedTraversers.add(this.haltedTraverserStrategy.halt(endStep.next()));
            }
            // the result of a TraversalVertexProgram are the halted traversers
            memory.set(HALTED_TRAVERSERS, haltedTraversers);
            // finalize profile side-effect steps. (todo: try and hide this)
            for (final ProfileSideEffectStep profileStep : TraversalHelper.getStepsOfAssignableClassRecursively(ProfileSideEffectStep.class, this.traversal.get())) {
                this.traversal.get().getSideEffects().set(profileStep.getSideEffectKey(), profileStep.generateFinalResult(this.traversal.get().getSideEffects().get(profileStep.getSideEffectKey())));
            }
            return true;
        }
    } else {
        return false;
    }
}
 
Example 19
Source File: MedianVertexProgram.java    From grakn with GNU Affero General Public License v3.0 4 votes vote down vote up
@Override
public boolean terminate(final Memory memory) {
    LOGGER.debug("Finished Iteration {}", memory.getIteration());

    if (memory.getIteration() == 2) {
        memory.set(INDEX_START, 0L);
        memory.set(INDEX_END, memory.<Long>get(COUNT) - 1L);
        memory.set(INDEX_MEDIAN, (memory.<Long>get(COUNT) - 1L) / 2L);

        LOGGER.debug("count: {}", memory.<Long>get(COUNT));
        LOGGER.debug("first pivot: {}", memory.<Long>get(PIVOT));

    } else if (memory.getIteration() > 2) {

        long indexNegativeEnd = memory.<Long>get(INDEX_START) + memory.<Long>get(NEGATIVE_COUNT) - 1;
        long indexPositiveStart = memory.<Long>get(INDEX_END) - memory.<Long>get(POSITIVE_COUNT) + 1;

        LOGGER.debug("pivot: {}", memory.<Long>get(PIVOT));

        LOGGER.debug("{}, {}", memory.<Long>get(INDEX_START), indexNegativeEnd);
        LOGGER.debug("{}, {}", indexPositiveStart, memory.<Long>get(INDEX_END));

        LOGGER.debug("negative count: {}", memory.<Long>get(NEGATIVE_COUNT));
        LOGGER.debug("positive count: {}", memory.<Long>get(POSITIVE_COUNT));

        LOGGER.debug("negative pivot: {}", memory.<Long>get(PIVOT_NEGATIVE));
        LOGGER.debug("positive pivot: {}", memory.<Long>get(PIVOT_POSITIVE));

        if (indexNegativeEnd < memory.<Long>get(INDEX_MEDIAN)) {
            if (indexPositiveStart > memory.<Long>get(INDEX_MEDIAN)) {
                memory.set(FOUND, true);
                LOGGER.debug("FOUND IT!!!");
            } else {
                memory.set(INDEX_START, indexPositiveStart);
                memory.set(PIVOT, memory.get(PIVOT_POSITIVE));
                memory.set(LABEL_SELECTED, memory.getIteration());
                LOGGER.debug("new pivot: {}", memory.<Long>get(PIVOT));
            }
        } else {
            memory.set(INDEX_END, indexNegativeEnd);
            memory.set(PIVOT, memory.get(PIVOT_NEGATIVE));
            memory.set(LABEL_SELECTED, -memory.getIteration());
            LOGGER.debug("new pivot: {}", memory.<Long>get(PIVOT));
        }
        memory.set(MEDIAN, memory.get(PIVOT));

        memory.set(POSITIVE_COUNT, 0L);
        memory.set(NEGATIVE_COUNT, 0L);
    }

    return memory.<Boolean>get(FOUND) || memory.getIteration() >= MAX_ITERATION;
}