<commit_before>package kademlia.operation;

import java.io.IOException;
import java.util.List;
import kademlia.KademliaNode;
import kademlia.core.KadConfiguration;
import kademlia.core.KadServer;
import kademlia.dht.DHT;
import kademlia.dht.StorageEntryMetadata;
import kademlia.exceptions.ContentNotFoundException;
import kademlia.message.Message;
import kademlia.message.StoreContentMessage;
import kademlia.node.Node;

/**
 * Refresh/Restore the data on this node by sending the data to the K-Closest nodes to the data
 *
 * @author <NAME>
 * @since 20140306
 */
public class ContentRefreshOperation implements Operation
{

    private final KadServer server;
    private final KademliaNode localNode;
    private final DHT dht;
    private final KadConfiguration config;

    public ContentRefreshOperation(KadServer server, KademliaNode localNode, DHT dht, KadConfiguration config)
    {
        this.server = server;
        this.localNode = localNode;
        this.dht = dht;
        this.config = config;
    }

    /**
     * For each content stored on this DHT, distribute it to the K closest nodes
     * Also delete the content if this node is no longer one of the K closest nodes
     *
     * We assume that our RoutingTable is updated, and we can get the K closest nodes from that table
     *
     * @throws java.io.IOException
     */
    @Override
    public void execute() throws IOException
    {
        /* Get a list of all storage entries for content */
        List<StorageEntryMetadata> entries = this.dht.getStorageEntries();

        /* If a content was last republished before this time, then we need to republish it */
        final long minRepublishTime = (System.currentTimeMillis() / 1000L) - this.config.restoreInterval();

        /* For each storage entry, distribute it */
        for (StorageEntryMetadata e : entries)
        {
            /* Check last update time of this entry and only distribute it if it has been last updated > 1 hour ago */
            if (e.lastRepublished() > minRepublishTime)
            {
                continue;
            }

            /* Set that this content is now republished */
            e.updateLastRepublished();

            /* Get the K closest nodes to this entries */
            List<Node> closestNodes = this.localNode.getRoutingTable().findClosest(e.getKey(), this.config.k());

            /* Create the message */
            Message msg = new StoreContentMessage(this.localNode.getNode(), dht.get(e));

            /*Store the message on all of the K-Nodes*/
            for (Node n : closestNodes)
            {
                /*We don't need to again store the content locally, it's already here*/
                if (!n.equals(this.localNode.getNode()))
                {
                    /* Send a contentstore operation to the K-Closest nodes */
                    this.server.sendMessage(n, msg, null);
                }
            }

            /* Delete any content on this node that this node is not one of the K-Closest nodes to */
            try
            {
                if (!closestNodes.contains(this.localNode.getNode()))
                {
                    this.dht.remove(e);
                }
            }
            catch (ContentNotFoundException cnfe)
            {
                /* It would be weird if the content is not found here */<commit_msg>ContentRefreshOperation - If a content is cached but this node is not one of the k-node for the content  -- Then this node is not responsible for republishing the content; handled that here! - The node also republishes the content if it's the owner since we assume the owner always have the latest content! -- made that change also<commit_after>package kademlia.operation;

import java.io.IOException;
import java.util.List;
import kademlia.KademliaNode;
import kademlia.core.KadConfiguration;
import kademlia.core.KadServer;
import kademlia.dht.DHT;
import kademlia.dht.StorageEntryMetadata;
import kademlia.exceptions.ContentNotFoundException;
import kademlia.message.Message;
import kademlia.message.StoreContentMessage;
import kademlia.node.Node;

/**
 * Refresh/Restore the data on this node by sending the data to the K-Closest nodes to the data
 *
 * @author <NAME>
 * @since 20140306
 */
public class ContentRefreshOperation implements Operation
{

    private final KadServer server;
    private final KademliaNode localNode;
    private final DHT dht;
    private final KadConfiguration config;

    public ContentRefreshOperation(KadServer server, KademliaNode localNode, DHT dht, KadConfiguration config)
    {
        this.server = server;
        this.localNode = localNode;
        this.dht = dht;
        this.config = config;
    }

    /**
     * For each content stored on this DHT, distribute it to the K closest nodes
     * Also delete the content if this node is no longer one of the K closest nodes
     *
     * We assume that our RoutingTable is updated, and we can get the K closest nodes from that table
     *
     * @throws java.io.IOException
     */
    @Override
    public void execute() throws IOException
    {
        /* Get a list of all storage entries for content */
        List<StorageEntryMetadata> entries = this.dht.getStorageEntries();

        /* If a content was last republished before this time, then we need to republish it */
        final long minRepublishTime = (System.currentTimeMillis() / 1000L) - this.config.restoreInterval();

        /* For each storage entry, distribute it */
        for (StorageEntryMetadata e : entries)
        {
            /* Check last update time of this entry and only distribute it if it has been last updated > 1 hour ago */
            if (e.lastRepublished() > minRepublishTime)
            {
                continue;
            }

            /* If this is a cached content and we're not one of the k-closest nodes nor the owner; this node is not responsible for republishing it */
            if (e.isCached() && !e.isKNode() && !e.getOwnerId().equals(this.localNode.getOwnerId()))
            {
                continue;
            }

            /* Set that this content is now republished */
            e.updateLastRepublished();

            /* Get the K closest nodes to this entries */
            List<Node> closestNodes = this.localNode.getRoutingTable().findClosest(e.getKey(), this.config.k());

            /* Create the message */
            Message msg = new StoreContentMessage(this.localNode.getNode(), dht.get(e));

            /*Store the message on all of the K-Nodes*/
            for (Node n : closestNodes)
            {
                /*We don't need to again store the content locally, it's already here*/
                if (!n.equals(this.localNode.getNode()))
                {
                    /* Send a contentstore operation to the K-Closest nodes */
                    this.server.sendMessage(n, msg, null);
                }
            }

            /* Delete any content on this node that this node is not one of the K-Closest nodes to */
            try
            {
                if (!closestNodes.contains(this.localNode.getNode()))
                {
                    this.dht.remove(e);
                }
            }
            catch (ContentNotFoundException cnfe)
            {
                /* It would be weird if the content is not found here */
{'fraction_non_alphanumeric': 0.07871562118954072, 'fraction_numerical': 0.003522557918981168, 'mean_word_length': 2.142613878246062, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, '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': '2136118', 'n_tokens_mistral': 1959, 'n_tokens_neox': 1880, 'n_words': 696}