MetisPIT * metisStandardPIT_Create(MetisForwarder *metis) { assertNotNull(metis, "Parameter must be non-null"); size_t allocation = sizeof(MetisPIT) + sizeof(MetisStandardPIT); MetisPIT *generic = parcMemory_AllocateAndClear(allocation); assertNotNull(generic, "parcMemory_AllocateAndClear(%zu) returned NULL", allocation); generic->closure = (uint8_t *) generic + sizeof(MetisPIT); MetisStandardPIT *pit = metisPIT_Closure(generic); pit->metis = metis; pit->logger = metisLogger_Acquire(metisForwarder_GetLogger(metis)); pit->table = metisMatchingRulesTable_Create(_metisPIT_PitEntryDestroyer); if (metisLogger_IsLoggable(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug)) { metisLogger_Log(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug, __func__, "PIT %p created", (void *) pit); } generic->getPitEntry = _metisStandardPIT_GetPitEntry; generic->receiveInterest = _metisStandardPIT_ReceiveInterest; generic->release = _metisStandardPIT_Destroy; generic->removeInterest = _metisStandardPIT_RemoveInterest; generic->satisfyInterest = _metisStandardPIT_SatisfyInterest; return generic; }
static void _mockPITInterface_Release(MetisPIT **pitPtr) { _MockPIT *mock = metisPIT_Closure(*pitPtr); mock->countRelease++; *pitPtr = NULL; }
static MetisNumberSet * _metisStandardPIT_SatisfyInterest(MetisPIT *generic, const MetisMessage *objectMessage) { assertNotNull(generic, "Parameter pit must be non-null"); assertNotNull(objectMessage, "Parameter objectMessage must be non-null"); MetisStandardPIT *pit = metisPIT_Closure(generic); // we need to look in all three tables to see if there's anything // to satisy in each of them and take the union of the reverse path sets. MetisNumberSet *ingressSetUnion = metisNumberSet_Create(); PARCArrayList *list = metisMatchingRulesTable_GetUnion(pit->table, objectMessage); for (size_t i = 0; i < parcArrayList_Size(list); i++) { MetisPitEntry *pitEntry = (MetisPitEntry *) parcArrayList_Get(list, i); // this is a reference counted return const MetisNumberSet *ingressSet = metisPitEntry_GetIngressSet(pitEntry); metisNumberSet_AddSet(ingressSetUnion, ingressSet); // and remove it from the PIT. Key is a reference counted copy of the pit entry message MetisMessage *key = metisPitEntry_GetMessage(pitEntry); metisMatchingRulesTable_RemoveFromBest(pit->table, key); metisMessage_Release(&key); } parcArrayList_Destroy(&list); return ingressSetUnion; }
static MetisPITVerdict _mockPITInterface_ReceiveInterest(MetisPIT *pit, MetisMessage *interestMessage) { _MockPIT *mock = metisPIT_Closure(pit); mock->countReceiveInterest++; return MetisPITVerdict_Aggregate; }
LONGBOW_TEST_CASE(Global, metisPIT_Closure) { MetisPIT *pit = _mockPIT_Create(); _MockPIT *mock = metisPIT_Closure(pit); assertTrue(mock == pit->closure, "Wrong pointer expected %p got %p", pit->closure, mock); _metisPIT_Release(&pit); }
static MetisPitEntry * _mockPITInterface_GetPitEntry(const MetisPIT *pit, const MetisMessage *interestMessage) { _MockPIT *mock = metisPIT_Closure(pit); mock->countGetPitEntry++; return NULL; }
static MetisNumberSet * _mockPITInterface_SatisfyInterest(MetisPIT *pit, const MetisMessage *objectMessage) { _MockPIT *mock = metisPIT_Closure(pit); mock->countSatisfyInterest++; return NULL; }
LONGBOW_TEST_CASE(Global, metisPIT_GetPitEntry) { MetisPIT *pit = _mockPIT_Create(); _MockPIT *mock = metisPIT_Closure(pit); metisPIT_GetPitEntry(pit, NULL); assertTrue(mock->countGetPitEntry == 1, "Wrong count expected 1 got %u", mock->countGetPitEntry); _metisPIT_Release(&pit); }
LONGBOW_TEST_CASE(Global, metisPIT_RemoveInterest) { MetisPIT *pit = _mockPIT_Create(); _MockPIT *mock = metisPIT_Closure(pit); metisPIT_RemoveInterest(pit, NULL); assertTrue(mock->countRemoveInterest == 1, "Wrong count expected 1 got %u", mock->countRemoveInterest); _metisPIT_Release(&pit); }
LONGBOW_TEST_CASE(Global, metisPIT_Release) { MetisPIT *pit = _mockPIT_Create(); MetisPIT *original = pit; _MockPIT *mock = metisPIT_Closure(pit); metisPIT_Release(&pit); assertTrue(mock->countRelease == 1, "Wrong count expected 1 got %u", mock->countRelease); _metisPIT_Release(&original); }
// There's a bit too much going on in this function, need to break it // apart for testability and style. static MetisPITVerdict _metisStandardPIT_ReceiveInterest(MetisPIT *generic, MetisMessage *interestMessage) { assertNotNull(generic, "Parameter pit must be non-null"); assertNotNull(interestMessage, "Parameter interestMessage must be non-null"); MetisStandardPIT *pit = metisPIT_Closure(generic); MetisPitEntry *pitEntry = metisMatchingRulesTable_Get(pit->table, interestMessage); if (pitEntry) { // has it expired? MetisTicks now = metisForwarder_GetTicks(pit->metis); if (now < metisPitEntry_GetExpiryTime(pitEntry)) { // what should we do about extending the lifetime? (case 819) _metisPIT_ExtendLifetime(pit, pitEntry, interestMessage); // Is the reverse path already in the PIT entry? if (_metisPIT_IngressSetContains(pitEntry, metisMessage_GetIngressConnectionId(interestMessage))) { // It is already in the PIT entry, so this is a retransmission, so forward it. if (metisLogger_IsLoggable(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug)) { metisLogger_Log(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug, __func__, "Message %p existing entry (expiry %" PRIu64 ") and reverse path, forwarding", (void *) interestMessage, metisPitEntry_GetExpiryTime(pitEntry)); } return MetisPITVerdict_Forward; } // It is in the PIT but this is the first interest for the reverse path metisPitEntry_AddIngressId(pitEntry, metisMessage_GetIngressConnectionId(interestMessage)); if (metisLogger_IsLoggable(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug)) { metisLogger_Log(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug, __func__, "Message %p existing entry (expiry %" PRIu64 ") and reverse path is new, aggregate", (void *) interestMessage, metisPitEntry_GetExpiryTime(pitEntry)); } return MetisPITVerdict_Aggregate; } // it's an old entry, remove it metisMatchingRulesTable_RemoveFromBest(pit->table, interestMessage); } _metisPIT_StoreInTable(pit, interestMessage); return MetisPITVerdict_Forward; }
static void _metisPIT_AddEgressConnectionId(MetisPIT *generic, const MetisMessage *interestMessage, unsigned connectionId) { assertNotNull(generic, "Parameter pit must be non-null"); assertNotNull(interestMessage, "Parameter interestMessage must be non-null"); MetisStandardPIT *pit = metisPIT_Closure(generic); MetisPitEntry *entry = metisMatchingRulesTable_Get(pit->table, interestMessage); if (entry) { metisPitEntry_AddEgressId(entry, connectionId); } }
static MetisPitEntry * _metisStandardPIT_GetPitEntry(const MetisPIT *generic, const MetisMessage *interestMessage) { assertNotNull(generic, "Parameter pit must be non-null"); assertNotNull(interestMessage, "Parameter interestMessage must be non-null"); MetisStandardPIT *pit = metisPIT_Closure(generic); MetisPitEntry *entry = metisMatchingRulesTable_Get(pit->table, interestMessage); if (entry) { return metisPitEntry_Acquire(entry); } return NULL; }
static void _metisStandardPIT_RemoveInterest(MetisPIT *generic, const MetisMessage *interestMessage) { assertNotNull(generic, "Parameter pit must be non-null"); assertNotNull(interestMessage, "Parameter interestMessage must be non-null"); MetisStandardPIT *pit = metisPIT_Closure(generic); if (metisLogger_IsLoggable(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug)) { metisLogger_Log(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug, __func__, "Message %p removed from PIT", (void *) interestMessage); } metisMatchingRulesTable_RemoveFromBest(pit->table, interestMessage); }
static void _metisStandardPIT_Destroy(MetisPIT **pitPtr) { assertNotNull(pitPtr, "Parameter must be non-null double pointer"); assertNotNull(*pitPtr, "Parameter must dereference to non-null pointer"); MetisStandardPIT *pit = metisPIT_Closure(*pitPtr); if (metisLogger_IsLoggable(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug)) { metisLogger_Log(pit->logger, MetisLoggerFacility_Processor, PARCLogLevel_Debug, __func__, "PIT %p destroyed", (void *) pit); } metisMatchingRulesTable_Destroy(&pit->table); metisLogger_Release(&pit->logger); parcMemory_Deallocate(pitPtr); }
static void _mockPITInterface_RemoveInterest(MetisPIT *pit, const MetisMessage *interestMessage) { _MockPIT *mock = metisPIT_Closure(pit); mock->countRemoveInterest++; }