package com.subgraph.orchid.directory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.subgraph.orchid.Descriptor;
import com.subgraph.orchid.data.HexDigest;
import com.subgraph.orchid.misc.GuardedBy;
public class DescriptorCacheData <T extends Descriptor> {
/** 7 days */
private final static long EXPIRY_PERIOD = 7 * 24 * 60 * 60 * 1000;
@GuardedBy("this")
private final Map<HexDigest, T> descriptorMap;
@GuardedBy("this")
private final List<T> allDescriptors;
public DescriptorCacheData() {
this.descriptorMap = new HashMap<HexDigest, T>();
this.allDescriptors = new ArrayList<T>();
}
synchronized T findByDigest(HexDigest digest) {
return descriptorMap.get(digest);
}
synchronized List<T> getAllDescriptors() {
return new ArrayList<T>(allDescriptors);
}
synchronized boolean addDescriptor(T d) {
if(descriptorMap.containsKey(d.getDescriptorDigest())) {
return false;
}
descriptorMap.put(d.getDescriptorDigest(), d);
allDescriptors.add(d);
return true;
}
synchronized void clear() {
descriptorMap.clear();
allDescriptors.clear();
}
synchronized int cleanExpired() {
final Set<T> expired = getExpiredSet();
if(expired.isEmpty()) {
return 0;
}
clear();
int dropped = 0;
for(T d: allDescriptors) {
if(expired.contains(d)) {
dropped += d.getBodyLength();
} else {
addDescriptor(d);
}
}
return dropped;
}
private Set<T> getExpiredSet() {
final long now = System.currentTimeMillis();
final Set<T> expired = new HashSet<T>();
for(T d: allDescriptors) {
if(isExpired(d, now)) {
expired.add(d);
}
}
return expired;
}
private boolean isExpired(T d, long now) {
return d.getLastListed() != 0 && d.getLastListed() < (now - EXPIRY_PERIOD);
}
}