Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package jadex.platform.service.dht;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import jadex.bridge.IComponentStep;
import jadex.bridge.IInternalAccess;
import jadex.bridge.component.IExecutionFeature;
import jadex.bridge.service.annotation.Service;
import jadex.bridge.service.annotation.ServiceComponent;
import jadex.bridge.service.annotation.ServiceStart;
import jadex.bridge.service.search.SServiceProvider;
import jadex.bridge.service.types.dht.IDistributedKVStoreDebugService;
import jadex.bridge.service.types.dht.IDistributedKVStoreService;
import jadex.bridge.service.types.dht.IFinger;
import jadex.bridge.service.types.dht.IID;
import jadex.bridge.service.types.dht.IRingApplicationService;
import jadex.bridge.service.types.dht.IRingApplicationService.State;
import jadex.bridge.service.types.dht.RingNodeEvent;
import jadex.bridge.service.types.dht.StoreEntry;
import jadex.commons.future.DefaultResultListener;
import jadex.commons.future.DelegationResultListener;
import jadex.commons.future.ExceptionDelegationResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.IFuture;
import jadex.commons.future.IResultListener;
import jadex.commons.future.ISubscriptionIntermediateFuture;
import jadex.commons.future.IntermediateDefaultResultListener;
/**
* Service that allows storing of key/value pairs in a DHT ring.
*/
@Service
public class DistributedKVStoreService implements IDistributedKVStoreService, IDistributedKVStoreDebugService
{
/** Delay in ms between two stabilize runs **/
protected static final long CHECK_STORED_DATA_DELAY = 60 * 1000;
/** Map that stores the actual data. Key -> StoreEntry **/
protected Map keyMap;
/** The local Ring Node to access the DHT Ring. **/
protected IRingApplicationService ring;
/** The local ID **/
protected IID myId;
/** The local agent access. **/
@ServiceComponent
protected IInternalAccess agent;
/** The logger. **/
protected Logger logger;
/** Flag that indicates whether this Service is already usable. */
protected boolean initialized;
/** The execution Feature of the agent. **/
protected IExecutionFeature executor;
/**
* Constructor.
*/
public DistributedKVStoreService()
{
this.keyMap = new ConcurrentHashMap();
this.logger = Logger.getLogger(this.getClass().getName());
}
/**
* Sets the initialized flag.
*/
public void setInitialized(boolean value)
{
this.initialized = value;
}
/**
* Gets the initialized flag.
*/
public boolean isInitialized()
{
return initialized;
}
@ServiceStart
public void onServiceStarted() {
// System.out.println("KVStoreService started");
executor = agent.getComponentFeature(IExecutionFeature.class);
}
/**
* Set the local ringNode.
*
* @param ring the new ringNode
*/
public void setRingService(IRingApplicationService ring)
{
this.ring = ring;
myId = ring.getId().get();
ISubscriptionIntermediateFuture subscription = ring.subscribeForEvents();
IntermediateDefaultResultListener eventListener = new IntermediateDefaultResultListener()
{
public void intermediateResultAvailable(RingNodeEvent event)
{
eventReceived(event);
}
};
subscription.addIntermediateResultListener(eventListener);
}
/**
* Publish a key/value pair in the corresponding node.
*
* @param key The Key.
* @param value The Value.
* @return The ID of the node this key was saved in.
*/
public IFuture put(String key, Object value)
{
return store(key, value, false);
}
/**
* Add a key/value pair to the collection addressed by the given key.
*
* @param key The Key.
* @param value The Value to add.
* @return The ID of the node this key was saved in.
*/
public IFuture add(String key, Object value)
{
return store(key, value, true);
}
protected IFuture store(final String key, final Object value, final boolean addToCollection) {
return store(ID.get(key), key, value, addToCollection);
}
protected IFuture store(final IID hash, final String key, final Object value, final boolean addToCollection)
{
return executor.scheduleStep(new IComponentStep()
{
@Override
public IFuture execute(IInternalAccess ia)
{
log("store for " + key);
final Future ret = new Future();
ring.findSuccessor(hash).addResultListener(new DefaultResultListener()
{
@Override
public void resultAvailable(IFinger finger)
{
final IID nodeId = finger.getNodeId();
// if (providerId.equals(myCid)) {
if(nodeId.equals(myId))
{
// use local access
storeLocal(key, value, addToCollection).addResultListener(new DelegationResultListener(ret));
}
else
{
getStoreService(finger).addResultListener(new DefaultResultListener()
{
@Override
public void resultAvailable(IDistributedKVStoreService result)
{
log("Storing key: " + key + "(hash: " + hash + ")" + " in: " + nodeId);
IFuture publish;
if (addToCollection) {
publish = result.add(key, value);
} else {
publish = result.put(key, value);
}
// IFuture publish = result.publish(key, value);
publish.addResultListener(new DelegationResultListener(ret));
}
public void exceptionOccurred(Exception exception) {
log("Failed to store key: " + key + "(hash: " + hash + ")" + " in: " + nodeId);
};
});
}
}
});
return ret;
}
});
}
/**
* Store a key/value pair in the local map.
*
* @param key The key
* @param value The value
* @param addToCollection If true, the value will be added to the collection stored
* @return the ID of the local node.
*/
private IFuture storeLocal(String key, Object value, boolean addToCollection) {
IID hash = ID.get(key);
return storeLocal(hash, key, value, addToCollection);
}
/**
* Store a key/value pair in the local map.
*
* @param hash The hash
* @param key The key
* @param value The value
* @return the ID of the local node.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
protected IFuture storeLocal(final IID hash, final String key, final Object value, final boolean addToCollection) {
// if (!isResponsibleFor(hash)) {
// logger.log(Level.WARNING, myId + ": storeLocal called even if i do not feel responsible for: " + hash + ". My successor is " + ring.getSuccessor().get().getNodeId());
// }
// return executor.scheduleStep(new IComponentStep()
// {
//
// @Override
// public IFuture execute(IInternalAccess ia)
// {
StoreEntry entry = keyMap.get(key);
if (entry == null) {
entry = new StoreEntry(hash, key, addToCollection ? new ArrayList() : value);
keyMap.put(key, entry);
}
Object oldValue = entry.getValue();
if (addToCollection) {
if (oldValue instanceof Collection) {
Collection col = (Collection)oldValue;
col.add(value);
} else {
logger.severe("Tried to add value to a collection, but single value is already saved for key: " + key);
}
} else {
if (oldValue instanceof Collection) {
logger.warning("Replaced a collection instead of adding a value for key: " + key);
}
}
log("Stored key: " + key + "(hash: " + hash +")" + " locally.");
// System.out.println(myId + ": Stored key: " + key + "(hash: " + hash +")" + " locally.");
// System.out.println(keyMap.size());
// idMap.put(hash, entry);
return ring.getId();
// }
// });
}
/**
* Lookup a key and return the responsible Node ID.
*
* @param key Requested key.
* @return IID of the responsible node.
*/
public IFuture lookupResponsibleStore(String key) {
final Future ret = new Future();
// final IExecutionFeature execFeature = agent.getComponentFeature(IExecutionFeature.class);
final IID id = ID.get(key);
log("lookupResponsibleStore for " + key);
ring.findSuccessor(id).addResultListener(new ExceptionDelegationResultListener(ret)
{
@Override
public void customResultAvailable(IFinger result) throws Exception {
ret.setResult(result.getNodeId());
super.customResultAvailable(result);
}
});
return ret;
}
/**
* Lookup a key in the ring and return the saved value, if any.
*
* @param key Requested key.
* @return The retrieved value or null, if none.
*/
public IFuture> lookup(String key) {
return lookup(key, ID.get(key));
}
/**
* Lookup a key in the ring and return the saved value, if any.
*
* @param key Requested key.
* @param idHash The hashed key to find the corresponding node.
* @return The retrieved value or null, if none.
*/
public IFuture> lookup(final String key, final IID idHash)
{
// final Future