Пример #1
0
static void
_athenaLRUContentStore_PurgeContentStoreEntry(AthenaLRUContentStore *impl, _AthenaLRUContentStoreEntry *storeEntry)
{
    PARCObject *nameKey = _createHashableKey(ccnxContentObject_GetName(storeEntry->contentObject), NULL, NULL);
    parcHashMap_Remove(impl->tableByName, nameKey);
    parcObject_Release((PARCObject **) &nameKey);

    if (storeEntry->hasKeyId) {
        PARCObject *nameAndKeyIdKey = _createHashableKey(ccnxContentObject_GetName(storeEntry->contentObject),
                                                         storeEntry->keyId, NULL);
        parcHashMap_Remove(impl->tableByNameAndKeyId, nameAndKeyIdKey);
        parcObject_Release((PARCObject **) &nameAndKeyIdKey);
    }

    if (storeEntry->hasContentObjectHash) {
        PARCObject *nameAndContentObjectHashKey = _createHashableKey(
            ccnxContentObject_GetName(storeEntry->contentObject), NULL, storeEntry->contentObjectHash);
        parcHashMap_Remove(impl->tableByNameAndObjectHash, nameAndContentObjectHashKey);
        parcObject_Release((PARCObject **) &nameAndContentObjectHashKey);
    }

    parcSortedList_Remove(impl->listByExpiryTime, storeEntry);

    parcSortedList_Remove(impl->listByRecommendedCacheTime, storeEntry);

    impl->currentSizeInBytes -= storeEntry->sizeInBytes;

    _athenaLRUContentStore_RemoveContentStoreEntryFromLRU(impl, storeEntry);

    impl->numEntries--;
}
Пример #2
0
static CCNxContentObject *
//_athenaLRUContentStore_GetMatch(AthenaContentStoreImplementation *store, const CCNxName *name, const PARCBuffer *keyIdRestriction,
//                                const PARCBuffer *contentObjectHash)
_athenaLRUContentStore_GetMatch(AthenaContentStoreImplementation *store, const CCNxInterest *interest)
{
    CCNxContentObject *result = NULL;
    AthenaLRUContentStore *impl = (AthenaLRUContentStore *) store;
    _AthenaLRUContentStoreEntry *entry = NULL;

    CCNxName *name = ccnxInterest_GetName(interest);
    PARCBuffer *contentObjectHashRestriction = ccnxInterest_GetContentObjectHashRestriction(interest);
    PARCBuffer *keyIdRestriction = ccnxInterest_GetKeyIdRestriction(interest);

    if (contentObjectHashRestriction != NULL) {
        PARCObject *nameAndHashKey = _createHashableKey(name, NULL, contentObjectHashRestriction);
        entry = (_AthenaLRUContentStoreEntry *) parcHashMap_Get(impl->tableByNameAndObjectHash, nameAndHashKey);
        parcObject_Release((PARCObject **) &nameAndHashKey);
    }

    if ((entry == NULL) && (keyIdRestriction != NULL)) {
        PARCObject *nameAndKeyIdKey = _createHashableKey(name, keyIdRestriction, NULL);
        entry = (_AthenaLRUContentStoreEntry *) parcHashMap_Get(impl->tableByNameAndKeyId, nameAndKeyIdKey);
        parcObject_Release((PARCObject **) &nameAndKeyIdKey);
    }

    if (entry == NULL) {
        PARCObject *nameKey = _createHashableKey(name, NULL, NULL);
        entry = (_AthenaLRUContentStoreEntry *) parcHashMap_Get(impl->tableByName, nameKey);
        parcObject_Release((PARCObject **) &nameKey);
    }

    // Matching is done. Now check for validity, if necessary.

    if (entry != NULL) {
        // We found matching content. Now make sure it's not expired before returning it. If it is expired,
        // remove it from the store and don't return anything.
        if (entry->hasExpiryTime && (entry->expiryTime < parcClock_GetTime(impl->wallClock))) {
            _athenaLRUContentStore_PurgeContentStoreEntry(impl, entry);
            entry = NULL;
        }

        // XXX: TODO: Check that the KeyId, if any, was verified.
    }

    // At this point, the cached content is considered valid for responding with. Return it.
    if (entry != NULL) {
        result = entry->contentObject;

        // Update LRU so that the matched entry is at the top of the list.
        _moveContentStoreEntryToLRUHead(impl, entry);

        impl->stats.numMatchHits++;
    } else {
        impl->stats.numMatchMisses++;
    }

    return result;
}
Пример #3
0
static bool
_athenaLRUContentStore_RemoveMatch(AthenaContentStoreImplementation *store, const CCNxName *name,
                                   const PARCBuffer *keyIdRestriction, const PARCBuffer *contentObjectHash)
{
    AthenaLRUContentStore *impl = (AthenaLRUContentStore *) store;
    bool wasRemoved = false;

    if (contentObjectHash != NULL) {
        PARCObject *nameAndHashKey = _createHashableKey(name, NULL, contentObjectHash);
        _AthenaLRUContentStoreEntry *entry =
            (_AthenaLRUContentStoreEntry *) parcHashMap_Get(impl->tableByNameAndObjectHash, nameAndHashKey);
        parcObject_Release((PARCObject **) &nameAndHashKey);

        if (entry != NULL) {
            _athenaLRUContentStore_PurgeContentStoreEntry(store, entry);
            wasRemoved = true;
        }
    }

    if (!wasRemoved && keyIdRestriction != NULL) {
        PARCObject *nameAndKeyIdKey = _createHashableKey(name, keyIdRestriction, NULL);
        _AthenaLRUContentStoreEntry *entry = (_AthenaLRUContentStoreEntry *) parcHashMap_Get(impl->tableByNameAndKeyId,
                                                                                             nameAndKeyIdKey);
        parcObject_Release((PARCObject **) &nameAndKeyIdKey);

        if (entry != NULL) {
            _athenaLRUContentStore_PurgeContentStoreEntry(store, entry);
            wasRemoved = true;
        }
    }

    if (!wasRemoved) {
        PARCObject *nameKey = _createHashableKey(name, NULL, NULL);
        _AthenaLRUContentStoreEntry *entry = (_AthenaLRUContentStoreEntry *) parcHashMap_Get(impl->tableByName,
                                                                                             nameKey);
        parcObject_Release((PARCObject **) &nameKey);

        if (entry != NULL) {
            _athenaLRUContentStore_PurgeContentStoreEntry(store, entry);
            wasRemoved = true;
        }
    }

    return wasRemoved;
}
LONGBOW_TEST_CASE(Loca, _createHashableKey_Name)
{
    CCNxName *name1 = ccnxName_CreateFromURI("lci:/name/1");
    CCNxName *name2 = ccnxName_CreateFromURI("lci:/name/2");

    PARCObject *keyObj1 = _createHashableKey(name1, NULL, NULL);
    PARCObject *keyObj2 = _createHashableKey(name2, NULL, NULL);

    assertNotNull(keyObj1, "Expected non-null key object");
    assertNotNull(keyObj2, "Expected non-null key object");
    assertFalse(parcObject_HashCode(keyObj1) == 0, "Expected non zero hashcode");
    assertFalse(parcObject_HashCode(keyObj2) == 0, "Expected non zero hashcode");
    assertFalse(parcObject_HashCode(keyObj1) == parcObject_HashCode(keyObj2), "Expected different hashcodes");

    parcObject_Release((PARCObject **) &keyObj1);
    parcObject_Release((PARCObject **) &keyObj2);
    ccnxName_Release(&name1);
    ccnxName_Release(&name2);
}
LONGBOW_TEST_CASE(Loca, _createHashableKey_NameAndObjectHash)
{
    // Now try with key Ids.

    CCNxName *name1 = ccnxName_CreateFromURI("lci:/name/1");
    CCNxName *name2 = ccnxName_CreateFromURI("lci:/name/2");

    PARCBuffer *objHash1 = parcBuffer_WrapCString("hash 1");
    PARCBuffer *objHash2 = parcBuffer_WrapCString("hash 2");

    PARCObject *keyObj1 = _createHashableKey(name1, NULL, objHash1);
    PARCObject *keyObj2 = _createHashableKey(name1, NULL, NULL);

    assertFalse(parcObject_HashCode(keyObj1) == 0, "Expected non zero hashcode");
    assertFalse(parcObject_HashCode(keyObj2) == 0, "Expected non zero hashcode");
    assertFalse(parcObject_HashCode(keyObj1) == parcObject_HashCode(keyObj2), "Expected different hashcodes");

    parcObject_Release((PARCObject **) &keyObj1);
    parcObject_Release((PARCObject **) &keyObj2);

    // Different object hashes.

    keyObj1 = _createHashableKey(name1, NULL, objHash1);
    keyObj2 = _createHashableKey(name1, NULL, objHash2);

    assertFalse(parcObject_HashCode(keyObj1) == 0, "Expected non zero hashcode");
    assertFalse(parcObject_HashCode(keyObj2) == 0, "Expected non zero hashcode");
    assertFalse(parcObject_HashCode(keyObj1) == parcObject_HashCode(keyObj2), "Expected different hashcodes");

    parcObject_Release((PARCObject **) &keyObj1);
    parcObject_Release((PARCObject **) &keyObj2);
    parcBuffer_Release(&objHash1);
    parcBuffer_Release(&objHash2);

    // Now try with

    ccnxName_Release(&name1);
    ccnxName_Release(&name2);
}
Пример #6
0
static bool
_athenaLRUContentStore_PutLRUContentStoreEntry(AthenaContentStoreImplementation *store,
                                               const _AthenaLRUContentStoreEntry *entry)
{
    bool result = false;

    AthenaLRUContentStore *impl = (AthenaLRUContentStore *) store;

    // Enforce capacity limit. If adding the next store item would put us over the limit, we have to remove
    // entrie(s) until there is room.

    bool isEnoughRoomInStore = true;
    if ((entry->sizeInBytes + impl->currentSizeInBytes) > impl->maxSizeInBytes) {
        isEnoughRoomInStore = _makeRoomInStore(impl, entry->sizeInBytes);
    }

    if (isEnoughRoomInStore) {
        _AthenaLRUContentStoreEntry *newEntry = _athenaLRUContentStoreEntry_Acquire(entry);

        // New entries go to the HEAD of the LRU.
        _addContentStoreEntryToLRUHead(impl, newEntry);

        // DO NOT RELEASE the newEntry after adding it to the containers. We will let the LRU be responsible for the
        // final release. At this point, the reference count of the new LRUContentStoreEntry is 1 and the LRU
        // points to it. The other containers (hashmap indices, sorted lists, etc) can acquire and release on their
        // own, but the LRU holds the final reference.

        _AthenaLRUContentStoreEntry *existingEntry = NULL;
        CCNxName *name = ccnxContentObject_GetName(newEntry->contentObject);
        if (name != NULL) {
            PARCObject *nameKey = _createHashableKey(name, NULL, NULL);
            existingEntry = _addEntryToIndexTableIfNotAlreadyInIt(impl->tableByName, nameKey, newEntry);
            parcObject_Release((PARCObject **) &nameKey);
        }

        if (newEntry->hasKeyId) {
            PARCObject *nameAndKeyIdKey = _createHashableKey(name, newEntry->keyId, NULL);
            existingEntry = _addEntryToIndexTableIfNotAlreadyInIt(impl->tableByNameAndKeyId, nameAndKeyIdKey, newEntry);
            parcObject_Release((PARCObject **) &nameAndKeyIdKey);
        }

        if (newEntry->hasContentObjectHash) {
            PARCObject *nameAndObjectHashKey = _createHashableKey(name, NULL, newEntry->contentObjectHash);
            existingEntry = _addEntryToIndexTableIfNotAlreadyInIt(impl->tableByNameAndObjectHash, nameAndObjectHashKey,
                                                                  newEntry);
            parcObject_Release((PARCObject **) &nameAndObjectHashKey);
        }

        if (existingEntry != NULL && existingEntry->indexCount < 1) {
            // The existing entry is in no indexes, which means it cannot be matched and serves no further purpose.
            // Remove it completely from all containers.
            //printf("Releasing previously held store entry\n");
            _athenaLRUContentStore_PurgeContentStoreEntry(impl, existingEntry);
        }

        // Add the new entry to the time-ordered lists, if it has an RCT or ExpiryTime.
        if (newEntry->hasExpiryTime) {
            parcSortedList_Add(impl->listByExpiryTime, newEntry);
        }

        if (newEntry->hasRecommendedCacheTime) {
            parcSortedList_Add(impl->listByRecommendedCacheTime, newEntry);
        }

        impl->stats.numAdds++;
        impl->numEntries++;
        impl->currentSizeInBytes += newEntry->sizeInBytes;
        result = true;
    }

    return result;
}