use of i2p.bote.packet.dht.IndexPacketEntry in project i2p.i2p-bote by i2p.
the class IndexPacketFolder method deleteExpired.
/**
* Does not add a Deletion Record, just deletes the file.
*/
@Override
public synchronized void deleteExpired() {
long currentTime = System.currentTimeMillis();
for (IndexPacket indexPacket : this) {
// true if at least one entry was removed
boolean removed = false;
synchronized (indexPacket) {
Iterator<IndexPacketEntry> iterator = indexPacket.iterator();
while (iterator.hasNext()) {
IndexPacketEntry entry = iterator.next();
if (currentTime > entry.storeTime + EXPIRATION_TIME_MILLISECONDS) {
log.debug("Deleting expired index packet entry: file=<" + getFilename(indexPacket.getDhtKey()) + ">, emailPktKey=" + entry.emailPacketKey.toBase64());
iterator.remove();
removed = true;
}
}
if (removed)
// don't merge, but overwrite the file with the entry/entries removed
super.store(indexPacket);
}
}
}
use of i2p.bote.packet.dht.IndexPacketEntry in project i2p.i2p-bote by i2p.
the class IndexPacketFolder method individualPackets.
/**
* Overridden to put each index packet entry in its own index packet
*/
@Override
public Iterator<IndexPacket> individualPackets() {
final Iterator<IndexPacket> bigPackets = super.individualPackets();
return new Iterator<IndexPacket>() {
IndexPacket currentPacket;
Iterator<IndexPacketEntry> currentPacketIterator;
@Override
public boolean hasNext() {
if (currentPacketIterator != null && currentPacketIterator.hasNext())
return true;
while (bigPackets.hasNext()) {
currentPacket = bigPackets.next();
currentPacketIterator = currentPacket.iterator();
if (currentPacketIterator.hasNext())
return true;
}
return false;
}
@Override
public IndexPacket next() {
if (currentPacketIterator == null || !currentPacketIterator.hasNext()) {
currentPacket = bigPackets.next();
currentPacketIterator = currentPacket.iterator();
}
IndexPacketEntry entry = currentPacketIterator.next();
IndexPacket indexPacket = new IndexPacket(currentPacket.getDhtKey());
indexPacket.put(entry);
return indexPacket;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Not supported!");
}
};
}
use of i2p.bote.packet.dht.IndexPacketEntry in project i2p.i2p-bote by i2p.
the class IndexPacketFolder method storeAndCreateDeleteRequest.
@Override
public DeleteRequest storeAndCreateDeleteRequest(DhtStorablePacket packetToStore) {
if (!(packetToStore instanceof IndexPacket))
throw new IllegalArgumentException("Invalid packet type: " + packetToStore.getClass().getSimpleName() + "; this folder only stores packets of type " + IndexPacket.class.getSimpleName() + ".");
IndexPacket indexPacketToStore = (IndexPacket) packetToStore;
// set the time stamps before merging so existing ones don't change
setTimeStamps(indexPacketToStore);
// use super.retrieve() because we don't want to delete time stamps here
DhtStorablePacket existingPacket = super.retrieve(packetToStore.getDhtKey());
// make a Delete Request that contains any known-to-be-deleted DHT keys from the store request
String delFileName = getDeletionFileName(packetToStore.getDhtKey());
DeletionInfoPacket delInfo = createDelInfoPacket(delFileName);
IndexPacketDeleteRequest delRequest = null;
if (delInfo != null) {
delRequest = null;
for (IndexPacketEntry entry : indexPacketToStore) {
DeletionRecord delRecord = delInfo.getEntry(entry.emailPacketKey);
if (delRecord != null) {
// leave delRequest null until a DeletionRecord is found
if (delRequest == null)
delRequest = new IndexPacketDeleteRequest(indexPacketToStore.getDhtKey());
delRequest.put(delRecord.dhtKey, delRecord.delAuthorization);
}
}
}
// remove deleted entries from indexPacketToStore so they are not re-stored
if (delInfo != null && !delInfo.isEmpty())
for (DeletionRecord delRecord : delInfo) indexPacketToStore.remove(delRecord.dhtKey);
// The resulting packet may be too big for a datagram but we don't split it until a peer asks for it.
if (existingPacket instanceof IndexPacket)
indexPacketToStore = new IndexPacket(indexPacketToStore, (IndexPacket) existingPacket);
else if (existingPacket != null)
log.error("Packet of type " + existingPacket.getClass().getSimpleName() + " found in IndexPacketFolder.");
// don't merge, but overwrite
super.store(indexPacketToStore);
return delRequest;
}
use of i2p.bote.packet.dht.IndexPacketEntry in project i2p.i2p-bote by i2p.
the class CheckEmailTask method call.
/**
* Returns <code>true</code> if a new email was created in the inbox as a result
* of receiving an email packet.
*/
@Override
public Boolean call() throws InterruptedException, ExecutionException, TimeoutException, GeneralSecurityException {
log.debug("Querying the DHT for index packets with key " + identity.getHash());
// Use findAll rather than findOne because some peers might have an incomplete set of
// Email Packet keys, and because we want to send IndexPacketDeleteRequests to all of them.
DhtResults indexPacketResults = dht.findAll(identity.getHash(), IndexPacket.class);
if (indexPacketResults.isEmpty())
return false;
Collection<IndexPacket> indexPackets = getIndexPackets(indexPacketResults.getPackets());
IndexPacket mergedPacket = new IndexPacket(indexPackets);
log.debug("Found " + mergedPacket.getNumEntries() + " Email Packet keys in " + indexPacketResults.getNumResults() + " Index Packets.");
newEmail = false;
indexPacketDeleteRequest = new IndexPacketDeleteRequest(identity.getHash());
Collection<Future<?>> futureResults = new ArrayList<Future<?>>();
ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS, EMAIL_PACKET_TASK_THREAD_FACTORY);
for (IndexPacketEntry entry : mergedPacket) {
Runnable task = new EmailPacketTask(entry.emailPacketKey);
futureResults.add(executor.submit(task));
}
// end all EmailPacketTask threads when tasks are finished
executor.shutdown();
// wait until all EmailPacketTasks are done
try {
for (Future<?> result : futureResults) result.get(1, TimeUnit.HOURS);
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
throw new InterruptedException("EmailPacketTask interrupted");
}
// delete index packets if all EmailPacketTasks finished without throwing an exception
Set<Destination> indexPacketPeers = indexPacketResults.getPeers();
if (indexPacketDeleteRequest.getNumEntries() > 0)
send(indexPacketDeleteRequest, indexPacketPeers);
return newEmail;
}
Aggregations