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);
}
Example #2
0
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;
}