LONGBOW_TEST_CASE(Local, putWithExpiryTime) { AthenaLRUContentStore *impl = _createLRUContentStore(); CCNxName *name1 = ccnxName_CreateFromURI("lci:/first/entry"); CCNxContentObject *contentObject1 = ccnxContentObject_CreateWithDataPayload(name1, NULL); CCNxName *name2 = ccnxName_CreateFromURI("lci:/second/entry"); CCNxContentObject *contentObject2 = ccnxContentObject_CreateWithDataPayload(name2, NULL); CCNxName *name3 = ccnxName_CreateFromURI("lci:/third/entry"); CCNxContentObject *contentObject3 = ccnxContentObject_CreateWithDataPayload(name3, NULL); uint64_t now = parcClock_GetTime(impl->wallClock); ccnxContentObject_SetExpiryTime(contentObject1, now + 200); // Expires AFTER object 2 ccnxContentObject_SetExpiryTime(contentObject2, now + 100); // contentObject3 has no expiry time, so it expires last. _AthenaLRUContentStoreEntry *entry1 = _athenaLRUContentStoreEntry_Create(contentObject1); _AthenaLRUContentStoreEntry *entry2 = _athenaLRUContentStoreEntry_Create(contentObject2); _AthenaLRUContentStoreEntry *entry3 = _athenaLRUContentStoreEntry_Create(contentObject3); bool status = _athenaLRUContentStore_PutContentObject(impl, contentObject1); assertTrue(status, "Exepected to insert content"); status = _athenaLRUContentStore_PutContentObject(impl, contentObject2); assertTrue(status, "Exepected to insert content"); _AthenaLRUContentStoreEntry *oldestEntry = _getEarliestExpiryTime(impl); assertTrue(oldestEntry->contentObject == entry2->contentObject, "Expected entry 2 to be the earliest expiring entry"); status = _athenaLRUContentStore_PutContentObject(impl, contentObject3); assertTrue(status, "Exepected to insert content"); // The entry with no expiration time should not affect list ordering. oldestEntry = _getEarliestExpiryTime(impl); assertTrue(oldestEntry->contentObject == entry2->contentObject, "Expected entry 2 to be the earliest expiring entry"); // Now remove the oldest one we added. The next oldest one should be contentObject1 _athenaLRUContentStore_RemoveMatch(impl, name2, NULL, NULL); // The entry with no expiration time should not affect list ordering. oldestEntry = _getEarliestExpiryTime(impl); assertTrue(oldestEntry->contentObject == entry1->contentObject, "Expected entry 1 to be the earliest expiring entry"); _athenaLRUContentStoreEntry_Release(&entry1); _athenaLRUContentStoreEntry_Release(&entry2); _athenaLRUContentStoreEntry_Release(&entry3); ccnxContentObject_Release(&contentObject1); ccnxContentObject_Release(&contentObject2); ccnxContentObject_Release(&contentObject3); ccnxName_Release(&name1); ccnxName_Release(&name2); ccnxName_Release(&name3); _athenaLRUContentStore_Release((AthenaContentStoreImplementation *) &impl); }
static bool _makeRoomInStore(AthenaLRUContentStore *impl, size_t sizeNeeded) { bool result = false; if (sizeNeeded > impl->maxSizeInBytes) { return false; // not possible. } uint64_t nowInMillis = parcClock_GetTime(impl->wallClock); // Evict expired items until we have enough room, or don't have any expired items. while (sizeNeeded > (impl->maxSizeInBytes - impl->currentSizeInBytes)) { _AthenaLRUContentStoreEntry *entry = _getEarliestExpiryTime(impl); if (entry == NULL) { break; } if (nowInMillis > entry->expiryTime) { _athenaLRUContentStore_PurgeContentStoreEntry(impl, entry); } else { break; } } // Evict items past their recommended cache time until we have enough room, or don't have any items. while (sizeNeeded > (impl->maxSizeInBytes - impl->currentSizeInBytes)) { _AthenaLRUContentStoreEntry *entry = _getEarliestRecommendedCacheTime(impl); if (entry == NULL) { break; } if (nowInMillis > entry->recommendedCacheTime) { _athenaLRUContentStore_PurgeContentStoreEntry(impl, entry); } else { break; } } while (sizeNeeded > (impl->maxSizeInBytes - impl->currentSizeInBytes)) { _AthenaLRUContentStoreEntry *entry = _getLeastUsedFromLRU(impl); if (entry == NULL) { break; } _athenaLRUContentStore_PurgeContentStoreEntry(impl, entry); } if (impl->maxSizeInBytes - impl->currentSizeInBytes > sizeNeeded) { return true; } return result; }