/// <summary> /// Add the Data packet to the cache so that it is available to use to /// answer interests. If data.getMetaInfo().getFreshnessPeriod() is not /// negative, set the staleness time to now plus the maximum of /// data.getMetaInfo().getFreshnessPeriod() and minimumCacheLifetime, which is /// checked during cleanup to remove stale content. /// This also checks if cleanupIntervalMilliseconds /// milliseconds have passed and removes stale content from the cache. After /// removing stale content, remove timed-out pending interests from /// storePendingInterest(), then if the added Data packet satisfies any /// interest, send it through the face and remove the interest from the pending /// interest table. /// </summary> /// /// <param name="data"></param> public void add(Data data) { double nowMilliseconds = net.named_data.jndn.util.Common.getNowMilliseconds(); doCleanup(nowMilliseconds); if (data.getMetaInfo().getFreshnessPeriod() >= 0.0d) { // The content will go stale, so use staleTimeCache_. MemoryContentCache.StaleTimeContent content = new MemoryContentCache.StaleTimeContent(data, nowMilliseconds, minimumCacheLifetime_); // Insert into staleTimeCache, sorted on content.cacheRemovalTimeMilliseconds_. // Search from the back since we expect it to go there. int i = staleTimeCache_.Count - 1; while (i >= 0) { if (staleTimeCache_[i].getCacheRemovalTimeMilliseconds() <= content .getCacheRemovalTimeMilliseconds()) { break; } --i; } // Element i is the greatest less than or equal to // content.cacheRemovalTimeMilliseconds_, so insert after it. staleTimeCache_.Insert(i + 1, content); } else { // The data does not go stale, so use noStaleTimeCache_. ILOG.J2CsMapping.Collections.Collections.Add(noStaleTimeCache_, new MemoryContentCache.Content(data)); } // Remove timed-out interests and check if the data packet matches any // pending interest. // Go backwards through the list so we can erase entries. for (int i_0 = pendingInterestTable_.Count - 1; i_0 >= 0; --i_0) { MemoryContentCache.PendingInterest pendingInterest = pendingInterestTable_[i_0]; if (pendingInterest.isTimedOut(nowMilliseconds)) { ILOG.J2CsMapping.Collections.Collections.RemoveAt(pendingInterestTable_, i_0); continue; } if (pendingInterest.getInterest().matchesName(data.getName())) { try { // Send to the same face from the original call to onInterest. // wireEncode returns the cached encoding if available. logger_.log(ILOG.J2CsMapping.Util.Logging.Level.INFO, "MemoryContentCache: Reply w/ add Data {0}", data.getName()); pendingInterest.getFace().send(data.wireEncode()); } catch (IOException ex) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, ex.Message); return; } // The pending interest is satisfied, so remove it. ILOG.J2CsMapping.Collections.Collections.RemoveAt(pendingInterestTable_, i_0); } } }
public void onInterest(Name prefix, Interest interest, Face face, long interestFilterId, InterestFilter filter) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.INFO, "MemoryContentCache: Received Interest {0}", interest.toUri()); double nowMilliseconds = net.named_data.jndn.util.Common.getNowMilliseconds(); doCleanup(nowMilliseconds); Name.Component selectedComponent = null; Blob selectedEncoding = null; // We need to iterate over both arrays. int totalSize = staleTimeCache_.Count + noStaleTimeCache_.Count; for (int i = 0; i < totalSize; ++i) { MemoryContentCache.Content content; bool isFresh = true; if (i < staleTimeCache_.Count) { MemoryContentCache.StaleTimeContent staleTimeContent = staleTimeCache_[i]; content = staleTimeContent; isFresh = staleTimeContent.isFresh(nowMilliseconds); } else { // We have iterated over the first array. Get from the second. content = noStaleTimeCache_[i - staleTimeCache_.Count]; } if (interest.matchesName(content.getName()) && !(interest.getMustBeFresh() && !isFresh)) { if (interest.getChildSelector() < 0) { // No child selector, so send the first match that we have found. logger_.log(ILOG.J2CsMapping.Util.Logging.Level.INFO, "MemoryContentCache: Reply Data {0}", content.getName()); try { face.send(content.getDataEncoding()); } catch (IOException ex) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, null, ex); } return; } else { // Update selectedEncoding based on the child selector. Name.Component component; if (content.getName().size() > interest.getName().size()) { component = content.getName().get( interest.getName().size()); } else { component = emptyComponent_; } bool gotBetterMatch = false; if (selectedEncoding == null) { // Save the first match. gotBetterMatch = true; } else { if (interest.getChildSelector() == 0) { // Leftmost child. if (component.compare(selectedComponent) < 0) { gotBetterMatch = true; } } else { // Rightmost child. if (component.compare(selectedComponent) > 0) { gotBetterMatch = true; } } } if (gotBetterMatch) { selectedComponent = component; selectedEncoding = content.getDataEncoding(); } } } } if (selectedEncoding != null) { // We found the leftmost or rightmost child. try { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.INFO, "MemoryContentCache: Reply Data to Interest {0}", interest.toUri()); face.send(selectedEncoding); } catch (IOException ex_0) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, null, ex_0); } } else { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.INFO, "MemoryContentCache: onDataNotFound for {0}", interest.toUri()); // Call the onDataNotFound callback (if defined). Object onDataNotFound = ILOG.J2CsMapping.Collections.Collections.Get(onDataNotFoundForPrefix_, prefix.toUri()); if (onDataNotFound != null) { try { ((OnInterestCallback)onDataNotFound).onInterest(prefix, interest, face, interestFilterId, filter); } catch (Exception ex_1) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onDataNotFound", ex_1); } } } }
/// <summary> /// Add the Data packet to the cache so that it is available to use to /// answer interests. If data.getMetaInfo().getFreshnessPeriod() is not /// negative, set the staleness time to now plus /// data.getMetaInfo().getFreshnessPeriod(), which is checked during cleanup to /// remove stale content. This also checks if cleanupIntervalMilliseconds /// milliseconds have passed and removes stale content from the cache. After /// removing stale content, remove timed-out pending interests from /// storePendingInterest(), then if the added Data packet satisfies any /// interest, send it through the face and remove the interest from the pending /// interest table. /// </summary> /// /// <param name="data"></param> public void add(Data data) { doCleanup(); if (data.getMetaInfo().getFreshnessPeriod() >= 0.0d) { // The content will go stale, so use staleTimeCache_. MemoryContentCache.StaleTimeContent content = new MemoryContentCache.StaleTimeContent (data); // Insert into staleTimeCache, sorted on content.staleTimeMilliseconds. // Search from the back since we expect it to go there. int i = staleTimeCache_.Count - 1; while (i >= 0) { if (staleTimeCache_[i].getStaleTimeMilliseconds() <= content .getStaleTimeMilliseconds()) break; --i; } // Element i is the greatest less than or equal to // content.staleTimeMilliseconds, so insert after it. staleTimeCache_.Insert(i + 1, content); } else // The data does not go stale, so use noStaleTimeCache_. ILOG.J2CsMapping.Collections.Collections.Add(noStaleTimeCache_,new MemoryContentCache.Content (data)); // Remove timed-out interests and check if the data packet matches any // pending interest. // Go backwards through the list so we can erase entries. double nowMilliseconds = net.named_data.jndn.util.Common.getNowMilliseconds(); for (int i_0 = pendingInterestTable_.Count - 1; i_0 >= 0; --i_0) { MemoryContentCache.PendingInterest pendingInterest = pendingInterestTable_[i_0]; if (pendingInterest.isTimedOut(nowMilliseconds)) { ILOG.J2CsMapping.Collections.Collections.RemoveAt(pendingInterestTable_,i_0); continue; } if (pendingInterest.getInterest().matchesName(data.getName())) { try { // Send to the same face from the original call to onInterest. // wireEncode returns the cached encoding if available. pendingInterest.getFace().send(data.wireEncode()); } catch (IOException ex) { ILOG.J2CsMapping.Util.Logging.Logger.getLogger(typeof(MemoryContentCache).FullName).log( ILOG.J2CsMapping.Util.Logging.Level.SEVERE, ex.Message); return; } // The pending interest is satisfied, so remove it. ILOG.J2CsMapping.Collections.Collections.RemoveAt(pendingInterestTable_,i_0); } } }