MetisContentStoreEntry * metisContentStoreEntry_Create(MetisMessage *contentMessage, MetisLruList *lruList) { assertNotNull(contentMessage, "Parameter objectMessage must be non-null"); MetisContentStoreEntry *entry = parcMemory_AllocateAndClear(sizeof(MetisContentStoreEntry)); assertNotNull(entry, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(MetisContentStoreEntry)); entry->message = metisMessage_Acquire(contentMessage); entry->refcount = 1; if (lruList != NULL) { entry->lruEntry = metisLruList_NewHeadEntry(lruList, entry); } entry->hasExpiryTimeTicks = metisMessage_HasExpiryTime(contentMessage); entry->hasRecommendedCacheTimeTicks = metisMessage_HasRecommendedCacheTime(contentMessage); if (entry->hasExpiryTimeTicks) { entry->expiryTimeTicks = metisMessage_GetExpiryTimeTicks(contentMessage); } if (entry->hasRecommendedCacheTimeTicks) { entry->recommendedCacheTimeTicks = metisMessage_GetRecommendedCacheTimeTicks(contentMessage); } return entry; }
LONGBOW_TEST_CASE(Global, metisMessage_HasRecommendedCacheTime) { PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); parcLogReporter_Release(&reporter); // Note: Assumes metisTestDataV0_EncodedObject doesn't have RCT. MetisMessage *message = metisMessage_CreateFromArray(metisTestDataV0_EncodedObject, sizeof(metisTestDataV0_EncodedObject), 1, 2, logger); metisLogger_Release(&logger); bool hasRCT = metisMessage_HasRecommendedCacheTime(message); assertFalse(hasRCT, "Message without hasRCT says it has one."); metisMessage_SetRecommendedCacheTimeTicks(message, 10000); hasRCT = metisMessage_HasRecommendedCacheTime(message); assertTrue(hasRCT, "Message with hasRCT says it doesn't have one."); metisMessage_Release(&message); }
static bool _metisLRUContentStore_PutContent(MetisContentStoreInterface *storeImpl, MetisMessage *content, uint64_t currentTimeTicks) { bool result = false; _MetisLRUContentStore *store = (_MetisLRUContentStore *) metisContentStoreInterface_GetPrivateData(storeImpl); assertNotNull(store, "Parameter store must be non-null"); assertNotNull(content, "Parameter objectMessage must be non-null"); assertTrue(metisMessage_GetType(content) == MetisMessagePacketType_ContentObject, "Parameter objectMessage must be a Content Object"); if (store->objectCapacity == 0) { return false; } uint64_t expiryTimeTicks = metisContentStoreEntry_MaxExpiryTime; uint64_t recommendedCacheTimeTicks = metisContentStoreEntry_MaxRecommendedCacheTime; if (metisMessage_HasExpiryTime(content)) { expiryTimeTicks = metisMessage_GetExpiryTimeTicks(content); } if (metisMessage_HasRecommendedCacheTime(content)) { recommendedCacheTimeTicks = metisMessage_GetRecommendedCacheTimeTicks(content); } // Don't add anything that's already expired or has exceeded RCT. if (currentTimeTicks >= expiryTimeTicks || currentTimeTicks >= recommendedCacheTimeTicks) { return false; } if (store->objectCount >= store->objectCapacity) { // Store is full. Need to make room. _evictByStorePolicy(store, currentTimeTicks); } // And now add a new entry to the head of the LRU. MetisContentStoreEntry *entry = metisContentStoreEntry_Create(content, store->lru); if (entry != NULL) { if (parcHashCodeTable_Add(store->storageByNameAndObjectHashHash, content, entry)) { parcHashCodeTable_Add(store->indexByNameHash, content, entry); if (metisMessage_HasKeyId(content)) { parcHashCodeTable_Add(store->indexByNameAndKeyIdHash, content, entry); } if (metisContentStoreEntry_HasExpiryTimeTicks(entry)) { metisTimeOrderedList_Add(store->indexByExpirationTime, entry); } if (metisContentStoreEntry_HasRecommendedCacheTimeTicks(entry)) { metisTimeOrderedList_Add(store->indexByRecommendedCacheTime, entry); } store->objectCount++; store->stats.countAdds++; if (metisLogger_IsLoggable(store->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug)) { metisLogger_Log(store->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug, __func__, "LRUContentStore %p saved message %p (object count %" PRIu64 ")", (void *) store, (void *) content, store->objectCount); } result = true; } else { // Free what we just created, but did not add. 'entry' has ownership of 'copy', and so will // call _Release() on it metisContentStoreEntry_Release(&entry); if (metisLogger_IsLoggable(store->logger, MetisLoggerFacility_Processor, PARCLogLevel_Warning)) { metisLogger_Log(store->logger, MetisLoggerFacility_Processor, PARCLogLevel_Warning, __func__, "LRUContentStore %p failed to add message %p to hash table", (void *) store, (void *) content); } } } return result; }