Example usage for java.util TreeSet removeIf

List of usage examples for java.util TreeSet removeIf

Introduction

In this page you can find the example usage for java.util TreeSet removeIf.

Prototype

default boolean removeIf(Predicate<? super E> filter) 

Source Link

Document

Removes all of the elements of this collection that satisfy the given predicate.

Usage

From source file:com.offbynull.voip.kademlia.FindSubcoroutine.java

@Override
public List<Node> run(Continuation cnt) throws Exception {
    Context ctx = (Context) cnt.getContext();

    ctx.addOutgoingMessage(subAddress, logAddress, info("Finding {}", findId));

    // Set up subcoroutine router
    Address routerAddress = subAddress.appendSuffix("finderreq" + idGenerator.generate());
    SubcoroutineRouter msgRouter = new SubcoroutineRouter(routerAddress, ctx);
    Controller msgRouterController = msgRouter.getController();

    // Get initial set of nodes to query from routing table
    List<Node> startNodes = router.find(findId, maxResults, false); // do not include stale nodes, we only want to contact alive nodes
    ctx.addOutgoingMessage(subAddress, logAddress,
            info("Route table entries closest to {}: {}", findId, startNodes));

    // Create sorted set of nodes to contact
    IdXorMetricComparator idClosenessComparator = new IdXorMetricComparator(findId);
    TreeSet<Node> contactSet = new TreeSet<>((x, y) -> idClosenessComparator.compare(x.getId(), y.getId()));
    contactSet.addAll(startNodes);// w  ww.j a v  a  2s . c o m

    // Create a sorted set of nodes to retain closest nodes in
    TreeSet<Node> closestSet = new TreeSet<>((x, y) -> idClosenessComparator.compare(x.getId(), y.getId()));

    // Execute requests
    Map<Subcoroutine<?>, Node> requestSubcoroutineToNodes = new HashMap<>(); // executing requests
    Set<Id> queriedSet = new HashSet<>(); // ids that have already been queried
    while (true) {
        // If there's room left to query more contacts that are closer to findId, do so... 
        while (msgRouterController.size() < maxConcurrentRequests && !contactSet.isEmpty()) {
            // Get next farthest away node to contact
            Node contactNode = contactSet.pollLast();

            // Add it to set of set of ids that have already been queried.. if it's already there, it means that it's already been
            // queried by this find, so skip it...
            boolean added = queriedSet.add(contactNode.getId());
            if (!added) {
                continue;
            }

            // Add it to the set of closest nodes (will be removed if node fails to respond)
            closestSet.add(contactNode);

            // If we already have maxResult closer nodes to findId, skip this node
            if (closestSet.size() > maxResults) {
                Node removedNode = closestSet.pollLast();
                if (removedNode == contactNode) {
                    continue;
                }
            }

            // Initialize query
            Address destinationAddress = addressTransformer.toAddress(contactNode.getLink())
                    .appendSuffix(ROUTER_EXT_HANDLER_RELATIVE_ADDRESS);
            RequestSubcoroutine<FindResponse> reqSubcoroutine = new RequestSubcoroutine.Builder<FindResponse>()
                    .sourceAddress(routerAddress, idGenerator).destinationAddress(destinationAddress)
                    .timerAddress(timerAddress)
                    .request(new FindRequest(advertiseSelf ? baseId : null, findId, maxResults))
                    .addExpectedResponseType(FindResponse.class).attemptInterval(Duration.ofSeconds(2L))
                    .maxAttempts(5).throwExceptionIfNoResponse(false).build();

            ctx.addOutgoingMessage(subAddress, logAddress, info("Querying node {}", contactNode));

            // Add query to router
            msgRouterController.add(reqSubcoroutine, AddBehaviour.ADD_PRIME_NO_FINISH);
            requestSubcoroutineToNodes.put(reqSubcoroutine, contactNode);
        }

        // If there are no more requests running, it means we're finished
        if (msgRouterController.size() == 0) {
            ctx.addOutgoingMessage(subAddress, logAddress, info("Find complete: {}", closestSet));
            return new ArrayList<>(closestSet);
        }

        // Wait for next messange forward to the router
        cnt.suspend();
        ForwardResult fr = msgRouter.forward();

        // If a request completed from the forwarded message
        if (fr.isForwarded() && fr.isCompleted()) { // calling isCompleted by itself may throw an exception, check isForwarded first
            // Get response
            FindResponse findResponse = (FindResponse) fr.getResult();

            if (findResponse == null) {
                // If failure, then mark as stale and remove from closest
                // DONT BOTHER WITH TRYING TO CALCULATE LOCKING/UNLOCKING LOGIC. THE LOGIC WILL BECOME EXTREMELY CONVOLUTED. THE QUERY
                // DID 5 REQUEST. IF NO ANSWER WAS GIVEN IN THE ALLOTED TIME, THEN MARK AS STALE!
                Node contactedNode = requestSubcoroutineToNodes.remove(fr.getSubcoroutine());
                try {
                    // not allowed to mark self as stale -- we may want to find self, but if we do and it's not responsive dont try to
                    // mark it as stale
                    if (!contactedNode.getId().equals(baseId)) {
                        router.stale(contactedNode);
                    }
                } catch (NodeNotFoundException nnfe) { // may have been removed (already marked as stale) / may not be in routing tree
                    // Do nothing
                }
                closestSet.remove(contactedNode);
            } else {
                // If success, then add returned nodes to contacts
                Node[] nodes = findResponse.getNodes();
                contactSet.addAll(Arrays.asList(nodes));

                // If we don't want to find our own ID / query ourselves... remove any reference to our own ID in the contactSet
                // TODO: optimize this by removing before it's added to contactSet
                if (ignoreSelf) {
                    contactSet.removeIf(x -> x.getId().equals(baseId));
                }
            }
        }
    }
}