28 const time::milliseconds InMemoryStorage::ZERO_WINDOW(0);
31 Cache::index<byFullName>::type::iterator it)
42 if (m_it != m_cache->get<byFullName>().end()) {
43 m_ptr = &((*m_it)->getData());
75 return m_it == rhs.m_it;
81 return m_it != rhs.m_it;
95 m_scheduler = make_unique<Scheduler>(ioService);
100 InMemoryStorage::init()
105 if (m_limit != std::numeric_limits<size_t>::max() && m_capacity > m_limit) {
106 m_capacity = m_limit;
109 for (
size_t i = 0; i < m_capacity; i++) {
117 Cache::iterator it = m_cache.begin();
118 while (it != m_cache.end()) {
122 BOOST_ASSERT(m_freeEntries.size() == m_capacity);
124 while (!m_freeEntries.empty()) {
125 delete m_freeEntries.top();
133 size_t oldCapacity = m_capacity;
134 m_capacity = capacity;
136 if (
size() > m_capacity) {
137 ssize_t nAllowedFailures =
size() - m_capacity;
138 while (
size() > m_capacity) {
139 if (!
evictItem() && --nAllowedFailures < 0) {
140 BOOST_THROW_EXCEPTION(
Error());
145 if (m_capacity >= oldCapacity) {
146 for (
size_t i = oldCapacity; i < m_capacity; i++) {
151 for (
size_t i = oldCapacity; i > m_capacity; i--) {
152 delete m_freeEntries.top();
157 BOOST_ASSERT(
size() + m_freeEntries.size() == m_capacity);
165 if (it != m_cache.get<byFullName>().end())
170 if (
isFull() && !doesReachLimit) {
177 if (
isFull() && doesReachLimit) {
182 BOOST_ASSERT(m_freeEntries.size() > 0);
187 entry->setData(data);
188 if (m_scheduler !=
nullptr && mustBeFreshProcessingWindow > ZERO_WINDOW) {
189 auto eventId = make_unique<util::scheduler::ScopedEventId>(*m_scheduler);
190 *eventId = m_scheduler->scheduleEvent(mustBeFreshProcessingWindow, [entry] { entry->markStale(); });
191 entry->setMarkStaleEventId(std::move(eventId));
193 m_cache.insert(entry);
199 shared_ptr<const Data>
202 auto it = m_cache.get<byFullName>().lower_bound(name);
205 if (it == m_cache.get<byFullName>().end()) {
215 return ((*it)->getData()).shared_from_this();
218 shared_ptr<const Data>
222 auto it = m_cache.get<byFullName>().
find(interest.
getName());
225 if (it != m_cache.get<byFullName>().end()) {
226 return ((*it)->getData()).shared_from_this();
231 it = m_cache.get<byFullName>().lower_bound(interest.
getName());
233 if (it == m_cache.get<byFullName>().end()) {
238 if (it != m_cache.get<byFullName>().begin()) {
243 if (ret ==
nullptr) {
249 return ret->
getData().shared_from_this();
252 InMemoryStorage::Cache::index<InMemoryStorage::byFullName>::type::iterator
253 InMemoryStorage::findNextFresh(Cache::index<byFullName>::type::iterator it)
const 255 for (; it != m_cache.get<byFullName>().
end(); it++) {
256 if ((*it)->isFresh())
264 InMemoryStorage::selectChild(
const Interest& interest,
265 Cache::index<byFullName>::type::iterator startingPoint)
const 267 BOOST_ASSERT(startingPoint != m_cache.get<byFullName>().end());
269 if (startingPoint != m_cache.get<byFullName>().begin()) {
270 BOOST_ASSERT((*startingPoint)->getFullName() < interest.
getName());
274 bool hasRightmostSelector = !hasLeftmostSelector;
278 startingPoint = findNextFresh(startingPoint);
281 if (startingPoint == m_cache.get<byFullName>().end()) {
285 if (hasLeftmostSelector) {
286 if (interest.
matchesData((*startingPoint)->getData())) {
287 return *startingPoint;
292 auto rightmost = startingPoint;
293 if (startingPoint != m_cache.get<byFullName>().end()) {
294 auto rightmostCandidate = startingPoint;
295 Name currentChildPrefix(
"");
298 ++rightmostCandidate;
301 rightmostCandidate = findNextFresh(rightmostCandidate);
304 bool isInBoundaries = (rightmostCandidate != m_cache.get<byFullName>().
end());
305 bool isInPrefix =
false;
306 if (isInBoundaries) {
307 isInPrefix = interest.
getName().
isPrefixOf((*rightmostCandidate)->getFullName());
311 if (interest.
matchesData((*rightmostCandidate)->getData())) {
312 if (hasLeftmostSelector) {
313 return *rightmostCandidate;
316 if (hasRightmostSelector) {
319 if (currentChildPrefix.
empty() || (childPrefix != currentChildPrefix)) {
320 currentChildPrefix = childPrefix;
321 rightmost = rightmostCandidate;
332 if (rightmost != startingPoint) {
336 if (hasRightmostSelector) {
337 if (interest.
matchesData((*startingPoint)->getData())) {
338 return *startingPoint;
345 InMemoryStorage::Cache::iterator
346 InMemoryStorage::freeEntry(Cache::iterator it)
350 m_freeEntries.push(*it);
352 return m_cache.erase(it);
359 auto it = m_cache.get<byFullName>().lower_bound(prefix);
360 while (it != m_cache.get<byFullName>().end() && prefix.
isPrefixOf((*it)->getName())) {
367 auto it = m_cache.get<byFullName>().
find(prefix);
368 if (it == m_cache.get<byFullName>().end())
376 if (m_freeEntries.size() > (2 *
size()))
383 auto it = m_cache.get<byFullName>().
find(name);
384 if (it == m_cache.get<byFullName>().end())
393 auto it = m_cache.get<byFullName>().
begin();
400 auto it = m_cache.get<byFullName>().
end();
423 for (
const auto& elem : m_cache.get<byFullName>())
424 os << elem->getFullName() << std::endl;
const Name & getName() const
Copyright (c) 2013-2017 Regents of the University of California.
void erase(const Name &prefix, const bool isPrefix=true)
Deletes in-memory storage entry by prefix by default.
void setCapacity(size_t nMaxPackets)
sets current capacity of in-memory storage (in packets)
virtual bool evictItem()=0
Removes one Data packet from in-memory storage based on derived class implemented replacement policy...
bool isFull() const
returns true if the in-memory storage uses up the current capacity, false otherwise ...
const_iterator & operator++()
virtual ~InMemoryStorage()
Represents an Interest packet.
bool operator==(const const_iterator &rhs)
boost::multi_index_container< InMemoryStorageEntry *, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< byFullName >, boost::multi_index::const_mem_fun< InMemoryStorageEntry, const Name &,&InMemoryStorageEntry::getFullName >, std::less< Name > > > > Cache
bool operator!=(const const_iterator &rhs)
size_t getCapacity() const
returns current capacity of in-memory storage (in packets)
int getChildSelector() const
virtual void beforeErase(InMemoryStorageEntry *entry)
Update the entry or other data structures before a entry is successfully erased according to derived ...
InMemoryStorage(size_t limit=std::numeric_limits< size_t >::max())
Create a InMemoryStorage with up to limit entries The InMemoryStorage created through this method wil...
Represents an error might be thrown during reduce the current capacity of the in-memory storage throu...
shared_ptr< const Data > find(const Interest &interest)
Finds the best match Data for an Interest.
virtual void afterAccess(InMemoryStorageEntry *entry)
Update the entry when the entry is returned by the find() function according to derived class impleme...
virtual void afterInsert(InMemoryStorageEntry *entry)
Update the entry or other data structures after a entry is successfully inserted according to derived...
Represents a self-defined const_iterator for the in-memory storage.
size_t size() const
Get number of components.
Represents an absolute name.
bool isPrefixOf(const Name &other) const
Check if this name is a prefix of another name.
bool matchesData(const Data &data) const
Check if Interest can be satisfied by data.
Represents an in-memory storage entry.
InMemoryStorage::const_iterator begin() const
Returns begin iterator of the in-memory storage ordering by name with digest.
const_iterator(const Data *ptr, const Cache *cache, Cache::index< byFullName >::type::iterator it)
const Data & getData() const
Returns the Data packet stored in the in-memory storage entry.
InMemoryStorage::const_iterator end() const
Returns end iterator of the in-memory storage ordering by name with digest.
void printCache(std::ostream &os) const
Prints contents of the in-memory storage.
bool empty() const
Check if name is empty.
void insert(const Data &data, const time::milliseconds &mustBeFreshProcessingWindow=INFINITE_WINDOW)
Inserts a Data packet.
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix of the name.
const Name & getFullName() const
Get full name including implicit digest.
Represents a Data packet.
bool getMustBeFresh() const
Check whether the MustBeFresh element is present.
void eraseImpl(const Name &name)
deletes in-memory storage entries by the Name with implicit digest.
static const time::milliseconds INFINITE_WINDOW