Added a KademliaStorageEntryMetadada Interface

- Updated the rest of the system to use this interface
This commit is contained in:
Joshua Kissoon 2014-06-02 14:44:51 +05:30
parent e8105a9e33
commit 4a9fd713fd
10 changed files with 121 additions and 38 deletions

View File

@ -67,7 +67,7 @@ public class DHT implements KademliaDHT
/* Lets check if we have this content and it's the updated version */ /* Lets check if we have this content and it's the updated version */
if (this.contentManager.contains(content.getContentMetadata())) if (this.contentManager.contains(content.getContentMetadata()))
{ {
StorageEntryMetadata current = this.contentManager.get(content.getContentMetadata()); KademliaStorageEntryMetadata current = this.contentManager.get(content.getContentMetadata());
/* update the last republished time */ /* update the last republished time */
current.updateLastRepublished(); current.updateLastRepublished();
@ -100,7 +100,7 @@ public class DHT implements KademliaDHT
{ {
//System.out.println("Adding new content."); //System.out.println("Adding new content.");
/* Keep track of this content in the entries manager */ /* Keep track of this content in the entries manager */
StorageEntryMetadata sEntry = this.contentManager.put(content.getContentMetadata()); KademliaStorageEntryMetadata sEntry = this.contentManager.put(content.getContentMetadata());
/* Now we store the content locally in a file */ /* Now we store the content locally in a file */
String contentStorageFolder = this.getContentStorageFolderName(content.getContentMetadata().getKey()); String contentStorageFolder = this.getContentStorageFolderName(content.getContentMetadata().getKey());
@ -144,7 +144,7 @@ public class DHT implements KademliaDHT
} }
@Override @Override
public KademliaStorageEntry get(StorageEntryMetadata entry) throws IOException, NoSuchElementException public KademliaStorageEntry get(KademliaStorageEntryMetadata entry) throws IOException, NoSuchElementException
{ {
try try
{ {
@ -169,7 +169,7 @@ public class DHT implements KademliaDHT
/* Load a KadContent if any exist for the given criteria */ /* Load a KadContent if any exist for the given criteria */
try try
{ {
StorageEntryMetadata e = this.contentManager.get(param); KademliaStorageEntryMetadata e = this.contentManager.get(param);
return this.retrieve(e.getKey(), e.hashCode()); return this.retrieve(e.getKey(), e.hashCode());
} }
catch (FileNotFoundException e) catch (FileNotFoundException e)
@ -192,7 +192,7 @@ public class DHT implements KademliaDHT
} }
@Override @Override
public void remove(StorageEntryMetadata entry) throws ContentNotFoundException public void remove(KademliaStorageEntryMetadata entry) throws ContentNotFoundException
{ {
String folder = this.getContentStorageFolderName(entry.getKey()); String folder = this.getContentStorageFolderName(entry.getKey());
File file = new File(folder + File.separator + entry.hashCode() + ".kct"); File file = new File(folder + File.separator + entry.hashCode() + ".kct");
@ -236,15 +236,15 @@ public class DHT implements KademliaDHT
} }
@Override @Override
public List<StorageEntryMetadata> getStorageEntries() public List<KademliaStorageEntryMetadata> getStorageEntries()
{ {
return contentManager.getAllEntries(); return contentManager.getAllEntries();
} }
@Override @Override
public void putStorageEntries(List<StorageEntryMetadata> ientries) public void putStorageEntries(List<KademliaStorageEntryMetadata> ientries)
{ {
for (StorageEntryMetadata e : ientries) for (KademliaStorageEntryMetadata e : ientries)
{ {
try try
{ {

View File

@ -69,7 +69,7 @@ public class GetParameter
* *
* @param md * @param md
*/ */
public GetParameter(StorageEntryMetadata md) public GetParameter(KademliaStorageEntryMetadata md)
{ {
this.key = md.getKey(); this.key = md.getKey();

View File

@ -81,7 +81,7 @@ public interface KademliaDHT
* *
* @throws java.io.IOException * @throws java.io.IOException
*/ */
public KademliaStorageEntry get(StorageEntryMetadata entry) throws IOException, NoSuchElementException; public KademliaStorageEntry get(KademliaStorageEntryMetadata entry) throws IOException, NoSuchElementException;
/** /**
* Get the StorageEntry for the content if any exist. * Get the StorageEntry for the content if any exist.
@ -104,12 +104,12 @@ public interface KademliaDHT
*/ */
public void remove(KadContent content) throws ContentNotFoundException; public void remove(KadContent content) throws ContentNotFoundException;
public void remove(StorageEntryMetadata entry) throws ContentNotFoundException; public void remove(KademliaStorageEntryMetadata entry) throws ContentNotFoundException;
/** /**
* @return A List of all StorageEntries for this node * @return A List of all StorageEntries for this node
*/ */
public List<StorageEntryMetadata> getStorageEntries(); public List<KademliaStorageEntryMetadata> getStorageEntries();
/** /**
* Used to add a list of storage entries for existing content to the DHT. * Used to add a list of storage entries for existing content to the DHT.
@ -117,6 +117,6 @@ public interface KademliaDHT
* *
* @param ientries The entries to add * @param ientries The entries to add
*/ */
public void putStorageEntries(List<StorageEntryMetadata> ientries); public void putStorageEntries(List<KademliaStorageEntryMetadata> ientries);
} }

View File

@ -9,9 +9,24 @@ package kademlia.dht;
public interface KademliaStorageEntry public interface KademliaStorageEntry
{ {
/**
* Add the content to the storage entry
*
* @param data The content data in byte[] format
*/
public void setContent(final byte[] data); public void setContent(final byte[] data);
/**
* Get the content from this storage entry
*
* @return The content in byte format
*/
public byte[] getContent(); public byte[] getContent();
public StorageEntryMetadata getContentMetadata(); /**
* Get the metadata for this storage entry
*
* @return the storage entry metadata
*/
public KademliaStorageEntryMetadata getContentMetadata();
} }

View File

@ -0,0 +1,59 @@
package kademlia.dht;
import kademlia.node.KademliaId;
/**
* Keeps track of data for a Content stored in the DHT
* Used by the StorageEntryManager class
*
* @author Joshua Kissoon
* @since 20140226
*/
public interface KademliaStorageEntryMetadata
{
/**
* @return The Kademlia ID of this content
*/
public KademliaId getKey();
/**
* @return The content's owner ID
*/
public String getOwnerId();
/**
* @return The type of this content
*/
public String getType();
/**
* @return A hash of the content
*/
public int getContentHash();
/**
* @return The last time this content was updated
*/
public long getLastUpdatedTimestamp();
/**
* When a node is looking for content, he sends the search criteria in a GetParameter object
* Here we take this GetParameter object and check if this StorageEntry satisfies the given parameters
*
* @param params
*
* @return boolean Whether this content satisfies the parameters
*/
public boolean satisfiesParameters(GetParameter params);
/**
* @return The timestamp for the last time this content was republished
*/
public long lastRepublished();
/**
* Whenever we republish a content or get this content from the network, we update the last republished time
*/
public void updateLastRepublished();
}

View File

@ -10,14 +10,14 @@ public class StorageEntry implements KademliaStorageEntry
{ {
private String content; private String content;
private final StorageEntryMetadata metadata; private final KademliaStorageEntryMetadata metadata;
public StorageEntry(final KadContent content) public StorageEntry(final KadContent content)
{ {
this(content, new StorageEntryMetadata(content)); this(content, new StorageEntryMetadata(content));
} }
public StorageEntry(final KadContent content, final StorageEntryMetadata metadata) public StorageEntry(final KadContent content, final KademliaStorageEntryMetadata metadata)
{ {
this.setContent(content.toSerializedForm()); this.setContent(content.toSerializedForm());
this.metadata = metadata; this.metadata = metadata;
@ -36,7 +36,7 @@ public class StorageEntry implements KademliaStorageEntry
} }
@Override @Override
public final StorageEntryMetadata getContentMetadata() public final KademliaStorageEntryMetadata getContentMetadata()
{ {
return this.metadata; return this.metadata;
} }

View File

@ -10,7 +10,7 @@ import kademlia.node.KademliaId;
* @author Joshua Kissoon * @author Joshua Kissoon
* @since 20140226 * @since 20140226
*/ */
public class StorageEntryMetadata public class StorageEntryMetadata implements KademliaStorageEntryMetadata
{ {
private final KademliaId key; private final KademliaId key;
@ -33,26 +33,31 @@ public class StorageEntryMetadata
this.lastRepublished = System.currentTimeMillis() / 1000L; this.lastRepublished = System.currentTimeMillis() / 1000L;
} }
@Override
public KademliaId getKey() public KademliaId getKey()
{ {
return this.key; return this.key;
} }
@Override
public String getOwnerId() public String getOwnerId()
{ {
return this.ownerId; return this.ownerId;
} }
@Override
public String getType() public String getType()
{ {
return this.type; return this.type;
} }
@Override
public int getContentHash() public int getContentHash()
{ {
return this.contentHash; return this.contentHash;
} }
@Override
public long getLastUpdatedTimestamp() public long getLastUpdatedTimestamp()
{ {
return this.updatedTs; return this.updatedTs;
@ -66,6 +71,7 @@ public class StorageEntryMetadata
* *
* @return boolean Whether this content satisfies the parameters * @return boolean Whether this content satisfies the parameters
*/ */
@Override
public boolean satisfiesParameters(GetParameter params) public boolean satisfiesParameters(GetParameter params)
{ {
/* Check that owner id matches */ /* Check that owner id matches */
@ -89,6 +95,7 @@ public class StorageEntryMetadata
return true; return true;
} }
@Override
public long lastRepublished() public long lastRepublished()
{ {
return this.lastRepublished; return this.lastRepublished;
@ -97,6 +104,7 @@ public class StorageEntryMetadata
/** /**
* Whenever we republish a content or get this content from the network, we update the last republished time * Whenever we republish a content or get this content from the network, we update the last republished time
*/ */
@Override
public void updateLastRepublished() public void updateLastRepublished()
{ {
this.lastRepublished = System.currentTimeMillis() / 1000L; this.lastRepublished = System.currentTimeMillis() / 1000L;
@ -105,7 +113,7 @@ public class StorageEntryMetadata
@Override @Override
public boolean equals(Object o) public boolean equals(Object o)
{ {
if (o instanceof StorageEntryMetadata) if (o instanceof KademliaStorageEntryMetadata)
{ {
return this.hashCode() == o.hashCode(); return this.hashCode() == o.hashCode();
} }

View File

@ -20,7 +20,7 @@ import kademlia.node.KademliaId;
class StoredContentManager class StoredContentManager
{ {
private final Map<KademliaId, List<StorageEntryMetadata>> entries; private final Map<KademliaId, List<KademliaStorageEntryMetadata>> entries;
{ {
@ -32,7 +32,7 @@ class StoredContentManager
* *
* @param content The content to store a reference to * @param content The content to store a reference to
*/ */
public StorageEntryMetadata put(KadContent content) throws ContentExistException public KademliaStorageEntryMetadata put(KadContent content) throws ContentExistException
{ {
return this.put(new StorageEntryMetadata(content)); return this.put(new StorageEntryMetadata(content));
} }
@ -42,7 +42,7 @@ class StoredContentManager
* *
* @param entry The StorageEntry to store * @param entry The StorageEntry to store
*/ */
public StorageEntryMetadata put(StorageEntryMetadata entry) throws ContentExistException public KademliaStorageEntryMetadata put(KademliaStorageEntryMetadata entry) throws ContentExistException
{ {
if (!this.entries.containsKey(entry.getKey())) if (!this.entries.containsKey(entry.getKey()))
{ {
@ -74,7 +74,7 @@ class StoredContentManager
if (this.entries.containsKey(param.getKey())) if (this.entries.containsKey(param.getKey()))
{ {
/* Content with this key exist, check if any match the rest of the search criteria */ /* Content with this key exist, check if any match the rest of the search criteria */
for (StorageEntryMetadata e : this.entries.get(param.getKey())) for (KademliaStorageEntryMetadata e : this.entries.get(param.getKey()))
{ {
/* If any entry satisfies the given parameters, return true */ /* If any entry satisfies the given parameters, return true */
if (e.satisfiesParameters(param)) if (e.satisfiesParameters(param))
@ -100,7 +100,7 @@ class StoredContentManager
/** /**
* Check if a StorageEntry exist on this DHT * Check if a StorageEntry exist on this DHT
*/ */
public synchronized boolean contains(StorageEntryMetadata entry) public synchronized boolean contains(KademliaStorageEntryMetadata entry)
{ {
return this.contains(new GetParameter(entry)); return this.contains(new GetParameter(entry));
} }
@ -112,12 +112,12 @@ class StoredContentManager
* *
* @return List of content for the specific search parameters * @return List of content for the specific search parameters
*/ */
public StorageEntryMetadata get(GetParameter param) throws NoSuchElementException public KademliaStorageEntryMetadata get(GetParameter param) throws NoSuchElementException
{ {
if (this.entries.containsKey(param.getKey())) if (this.entries.containsKey(param.getKey()))
{ {
/* Content with this key exist, check if any match the rest of the search criteria */ /* Content with this key exist, check if any match the rest of the search criteria */
for (StorageEntryMetadata e : this.entries.get(param.getKey())) for (KademliaStorageEntryMetadata e : this.entries.get(param.getKey()))
{ {
/* If any entry satisfies the given parameters, return true */ /* If any entry satisfies the given parameters, return true */
if (e.satisfiesParameters(param)) if (e.satisfiesParameters(param))
@ -135,7 +135,7 @@ class StoredContentManager
} }
} }
public StorageEntryMetadata get(StorageEntryMetadata md) public KademliaStorageEntryMetadata get(KademliaStorageEntryMetadata md)
{ {
return this.get(new GetParameter(md)); return this.get(new GetParameter(md));
} }
@ -143,11 +143,11 @@ class StoredContentManager
/** /**
* @return A list of all storage entries * @return A list of all storage entries
*/ */
public synchronized List<StorageEntryMetadata> getAllEntries() public synchronized List<KademliaStorageEntryMetadata> getAllEntries()
{ {
List<StorageEntryMetadata> entriesRet = new ArrayList<>(); List<KademliaStorageEntryMetadata> entriesRet = new ArrayList<>();
for (List<StorageEntryMetadata> entrySet : this.entries.values()) for (List<KademliaStorageEntryMetadata> entrySet : this.entries.values())
{ {
if (entrySet.size() > 0) if (entrySet.size() > 0)
{ {
@ -163,7 +163,7 @@ class StoredContentManager
this.remove(new StorageEntryMetadata(content)); this.remove(new StorageEntryMetadata(content));
} }
public void remove(StorageEntryMetadata entry) throws ContentNotFoundException public void remove(KademliaStorageEntryMetadata entry) throws ContentNotFoundException
{ {
if (contains(entry)) if (contains(entry))
{ {
@ -180,14 +180,14 @@ class StoredContentManager
{ {
StringBuilder sb = new StringBuilder("Stored Content: \n"); StringBuilder sb = new StringBuilder("Stored Content: \n");
int count = 0; int count = 0;
for (List<StorageEntryMetadata> es : this.entries.values()) for (List<KademliaStorageEntryMetadata> es : this.entries.values())
{ {
if (entries.size() < 1) if (entries.size() < 1)
{ {
continue; continue;
} }
for (StorageEntryMetadata e : es) for (KademliaStorageEntryMetadata e : es)
{ {
sb.append(++count); sb.append(++count);
sb.append(". "); sb.append(". ");

View File

@ -6,6 +6,7 @@ import kademlia.KadConfiguration;
import kademlia.KadServer; import kademlia.KadServer;
import kademlia.KademliaNode; import kademlia.KademliaNode;
import kademlia.dht.KademliaDHT; import kademlia.dht.KademliaDHT;
import kademlia.dht.KademliaStorageEntryMetadata;
import kademlia.dht.StorageEntryMetadata; import kademlia.dht.StorageEntryMetadata;
import kademlia.exceptions.ContentNotFoundException; import kademlia.exceptions.ContentNotFoundException;
import kademlia.message.Message; import kademlia.message.Message;
@ -46,13 +47,13 @@ public class ContentRefreshOperation implements Operation
public void execute() throws IOException public void execute() throws IOException
{ {
/* Get a list of all storage entries for content */ /* Get a list of all storage entries for content */
List<StorageEntryMetadata> entries = this.dht.getStorageEntries(); List<KademliaStorageEntryMetadata> entries = this.dht.getStorageEntries();
/* If a content was last republished before this time, then we need to republish it */ /* If a content was last republished before this time, then we need to republish it */
final long minRepublishTime = (System.currentTimeMillis() / 1000L) - this.config.restoreInterval(); final long minRepublishTime = (System.currentTimeMillis() / 1000L) - this.config.restoreInterval();
/* For each storage entry, distribute it */ /* For each storage entry, distribute it */
for (StorageEntryMetadata e : entries) for (KademliaStorageEntryMetadata e : entries)
{ {
/* Check last update time of this entry and only distribute it if it has been last updated > 1 hour ago */ /* Check last update time of this entry and only distribute it if it has been last updated > 1 hour ago */
if (e.lastRepublished() > minRepublishTime) if (e.lastRepublished() > minRepublishTime)

View File

@ -13,7 +13,7 @@ import java.lang.reflect.Type;
import java.util.List; import java.util.List;
import kademlia.dht.DHT; import kademlia.dht.DHT;
import kademlia.dht.KademliaDHT; import kademlia.dht.KademliaDHT;
import kademlia.dht.StorageEntryMetadata; import kademlia.dht.KademliaStorageEntryMetadata;
/** /**
* A KadSerializer that serializes DHT to JSON format * A KadSerializer that serializes DHT to JSON format
@ -49,7 +49,7 @@ public class JsonDHTSerializer implements KadSerializer<KademliaDHT>
{ {
gson = new Gson(); gson = new Gson();
storageEntriesCollectionType = new TypeToken<List<StorageEntryMetadata>>() storageEntriesCollectionType = new TypeToken<List<KademliaStorageEntryMetadata>>()
{ {
}.getType(); }.getType();
} }
@ -85,7 +85,7 @@ public class JsonDHTSerializer implements KadSerializer<KademliaDHT>
dht.initialize(); dht.initialize();
/* Now get the entries and add them back to the DHT */ /* Now get the entries and add them back to the DHT */
List<StorageEntryMetadata> entries = gson.fromJson(reader, this.storageEntriesCollectionType); List<KademliaStorageEntryMetadata> entries = gson.fromJson(reader, this.storageEntriesCollectionType);
dht.putStorageEntries(entries); dht.putStorageEntries(entries);
reader.endArray(); reader.endArray();