<commit_before>package it.unitn.ds.util;

import it.unitn.ds.server.Item;
import it.unitn.ds.server.Node;
import it.unitn.ds.server.NodeRemote;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;

/**
 * Convenient class to deal with RMI
 */
public abstract class RemoteUtil {

    private static final Logger logger = LogManager.getLogger();

    public static final String RMI_NODE = "rmi://localhost/NodeRemote";

    /**
     * Get reference to remote node given node id
     *
     * @param nodeId of the wanted node
     * @return reference to remote object
     */
    @Nullable
    public static NodeRemote getRemoteNode(int nodeId) {
        try {
            return ((NodeRemote) Naming.lookup(RMI_NODE + nodeId));
        } catch (Exception e) {
            logger.error("Failed to get remote node by nodeId=" + nodeId);
            return null;
        }
    }

    /**
     * Returns successor node clockwise in circle of the given node id in the set of nodes
     *
     * @param nodeId predecessor node id
     * @param nodes  set of possible successors
     * @return successor node of the given node id
     */
    @Nullable
    public static Node getSuccessorNode(int nodeId, TreeSet<Integer> nodes) throws RemoteException {
        logger.debug("NodeId=" + nodeId + " is searching for successorNode...");
        int successorNodeId = getSuccessorNodeId(nodeId, nodes);
        if (successorNodeId == nodeId) {
            logger.debug("NodeId=" + nodeId + " did not find successorNode, except itself");
            return null;
        }
        logger.debug("NodeId=" + nodeId + " found successorNodeId=" + successorNodeId);
        return getRemoteNode(successorNodeId).getNode();
    }

    private static int getSuccessorNodeId(int targetNodeId, TreeSet<Integer> nodes) {
        for (int nodeId : nodes) {
            if (nodeId > targetNodeId) {
                return nodeId;
            }
        }
        return nodes.iterator().next();
    }

    /**
     * Copies items from one node to another, keeps items of fromNode
     *
     * @param fromNode from which to transfer
     * @param toNode   to which to transfer
     */
    public static void copyItems(Node fromNode, Node toNode) throws RemoteException {
        if (fromNode.getItems().isEmpty()) {
            logger.debug("Nothing to copy fromNode=" + fromNode + " toNode=" + toNode);
            return;
        }
        ArrayList<Item> items = new ArrayList<>(fromNode.getItems().values());
        logger.debug("Coping items fromNode=" + fromNode + " toNode=" + toNode + " items=" + Arrays.toString(items.toArray()));
        getRemoteNode(toNode.getId()).updateItems(items);
    }

    /**
     * Transfers items from one node to another, removes items of fromNode
     *
     * @param fromNode from which to transfer
     * @param toNode   to which to transfer
     */
    public static void transferItems(Node fromNode, Node toNode) throws RemoteException {
        if (fromNode.getItems().isEmpty()) {
            logger.debug("Nothing to transfer fromNode=" + fromNode + " toNode=" + toNode);
            return;
        }
        List<Item> items = getTransferItems(fromNode, toNode);
        logger.debug("Transferring items fromNode=" + fromNode + " toNode=" + toNode + " items=" + Arrays.toString(items.toArray()));
        getRemoteNode(toNode.getId()).updateItems(items);
        getRemoteNode(fromNode.getId()).removeItems(items);
    }

    /**
     * Returns a list of items, that should be transferred contained in toNode
     *
     * @param fromNode from which to transfer
     * @param toNode   to which to transfer
     * @return list of items for toNode
     */
    private static List<Item> getTransferItems(Node fromNode, Node toNode) {
        List<Item> items = new ArrayList<>();
        for (Item item : fromNode.getItems().values()) {
            if (item.getKey() <= toNode.getId()) {
                items.add(item);
            } else {
                return items;
            }<commit_msg>corner case fixed for items transferred from last to first node over 0 axis<commit_after>package it.unitn.ds.util;

import it.unitn.ds.server.Item;
import it.unitn.ds.server.Node;
import it.unitn.ds.server.NodeRemote;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;

/**
 * Convenient class to deal with RMI
 */
public abstract class RemoteUtil {

    private static final Logger logger = LogManager.getLogger();

    public static final String RMI_NODE = "rmi://localhost/NodeRemote";

    /**
     * Get reference to remote node given node id
     *
     * @param nodeId of the wanted node
     * @return reference to remote object
     */
    @Nullable
    public static NodeRemote getRemoteNode(int nodeId) {
        try {
            return ((NodeRemote) Naming.lookup(RMI_NODE + nodeId));
        } catch (Exception e) {
            logger.error("Failed to get remote node by nodeId=" + nodeId);
            return null;
        }
    }

    /**
     * Returns successor node clockwise in circle of the given node id in the set of nodes
     *
     * @param nodeId predecessor node id
     * @param nodes  set of possible successors
     * @return successor node of the given node id
     */
    @Nullable
    public static Node getSuccessorNode(int nodeId, TreeSet<Integer> nodes) throws RemoteException {
        logger.debug("NodeId=" + nodeId + " is searching for successorNode...");
        int successorNodeId = getSuccessorNodeId(nodeId, nodes);
        if (successorNodeId == nodeId) {
            logger.debug("NodeId=" + nodeId + " did not find successorNode, except itself");
            return null;
        }
        logger.debug("NodeId=" + nodeId + " found successorNodeId=" + successorNodeId);
        return getRemoteNode(successorNodeId).getNode();
    }

    private static int getSuccessorNodeId(int targetNodeId, TreeSet<Integer> nodes) {
        for (int nodeId : nodes) {
            if (nodeId > targetNodeId) {
                return nodeId;
            }
        }
        return nodes.iterator().next();
    }

    /**
     * Copies items from one node to another, keeps items of fromNode
     *
     * @param fromNode from which to transfer
     * @param toNode   to which to transfer
     */
    public static void copyItems(Node fromNode, Node toNode) throws RemoteException {
        if (fromNode.getItems().isEmpty()) {
            logger.debug("Nothing to copy fromNode=" + fromNode + " toNode=" + toNode);
            return;
        }
        ArrayList<Item> items = new ArrayList<>(fromNode.getItems().values());
        logger.debug("Coping items fromNode=" + fromNode + " toNode=" + toNode + " items=" + Arrays.toString(items.toArray()));
        getRemoteNode(toNode.getId()).updateItems(items);
    }

    /**
     * Transfers items from one node to another, removes items of fromNode
     *
     * @param fromNode from which to transfer
     * @param toNode   to which to transfer
     */
    public static void transferItems(Node fromNode, Node toNode) throws RemoteException {
        if (fromNode.getItems().isEmpty()) {
            logger.debug("Nothing to transfer fromNode=" + fromNode + " toNode=" + toNode);
            return;
        }
        List<Item> items = getTransferItems(fromNode, toNode);
        logger.debug("Transferring items fromNode=" + fromNode + " toNode=" + toNode + " items=" + Arrays.toString(items.toArray()));
        getRemoteNode(toNode.getId()).updateItems(items);
        getRemoteNode(fromNode.getId()).removeItems(items);
    }

    /**
     * Returns a list of items, that should be transferred contained in toNode
     *
     * @param fromNode from which to transfer
     * @param toNode   to which to transfer
     * @return list of items for toNode
     */
    private static List<Item> getTransferItems(Node fromNode, Node toNode) {
        boolean isZeroCrossed = fromNode.getId() < toNode.getId();
        List<Item> items = new ArrayList<>();
        for (Item item : fromNode.getItems().values()) {
            if (item.getKey() <= toNode.getId()) {
                if (isZeroCrossed) {
                    if (item.getKey() > fromNode.getId()) {
                        items.add(item);
                    }
                } else {
                    items.add(item);
                }
            } else {
                return items;
            }
{'fraction_non_alphanumeric': 0.10565610859728507, 'fraction_numerical': 0.0005656108597285068, 'mean_word_length': 2.454865181711606, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4931128', 'n_tokens_mistral': 2439, 'n_tokens_neox': 2407, 'n_words': 718}