Project

General

Profile

Feature #4931 » async-strategy.cpp

meeting log - Ju Pan, 06/25/2019 02:06 PM

 
// in Strategy (naive)

class Strategy
{
public: // triggers
virtual void
afterNewNexthop(const pit::Entry& pitEntry);
};

// in forwarding (naive)

void triggerStrategyAfterNewNexthop(const fib::Entry& fibEntry) {

auto range = nt.partialEnumerate(fibEntry.getPrefix(),
[] (const name_tree::Entry& nte) -> std::pair<bool, bool> {
bool wantThis = nte.hasPitEntries() && nte.getFibEntry() != nullptr;
bool wantSubTree = nte.getFibEntry() != nullptr;
return std::make_pair(wantThis, wantSubTree);
});

for (const name_tree::Entry& nte : range) {
for (const shared_ptr<pit::Entry>& pitEntry : nte.getPitEntries()) {
// trigger strategy on pitEntry
// 1. lookup StrategyChoice table to determine effective strategy for pitEntry.getName()
// 2. invoke the strategy
}
}

}

// in Fib

class Fib
{
public:
signal::Signal<Fib, fib::Entry> afterNewNexthop;
};

// in forwarding, triggerStrategyAfterNewNexthop is connected to afterNewNexthop

// in Strategy (better)

class Strategy
{
public: // triggers
virtual bool
supportsNewNexthop() const;

virtual void
afterNewNexthop(const pit::Entry& pitEntry);
};

// ************************************************************************************************

// in forwarding (better)

void triggerStrategyAfterNewNexthop(const fib::Entry& fibEntry) {

auto range = nt.partialEnumerate(fibEntry.getPrefix(),
[] (const name_tree::Entry& nte) -> std::pair<bool, bool> {
// TODO is it possible to skip some enumeration
// 1. we should skip this subtree if no strategy within this subtree supports NewNexthop trigger
// 2. we can easily know the effective strategy for nte: either nte has SC, or nte's ancestor has it
// 3. but, how to know there's no other SC within subtree?
bool wantTree = nte.getFibEntry() != nullptr;
bool wantThis = nte.hasPitEntries() && wantTree;
return std::make_pair(wantThis, wantTree);
});

for (const name_tree::Entry& nte : range) {
// 1. lookup StrategyChoice table to determine effective strategy for nte.getName()
for (const shared_ptr<pit::Entry>& pitEntry : nte.getPitEntries()) {
// 2. trigger strategy on pitEntry
}
}

}

// a concrete strategy

// "building block" in a separate class does not make sense, because there's no logic other than "retain PIT entry".
// Creating a new strategy also does not make sense, because after FIB nexthop is in place, forwarding logic is almost same as forwarding new Interest,
// and that differs per strategy. Duplicating an existing strategy greatly increases code complexity and maintenance.

// Start with modifying BestRouteStrategy2, then AsfStrategy and MulticastStrategy.

class BestRouteStrategy2 : public Strategy
{
public:
void
afterReceiveInterest(const FaceEnpoint& ingress, const Interest& interest, const shared_ptr<pit::Entry>& pitEntry)
{
const fib::Entry& fibEntry = fib.lookup(pitEntry);
if (fibEntry_has_usable_nexthops) {
forward_to_these_nexthops();
} else if (pitEntry_has_existing_out_records) {
// do nothing
} else {
// this->sendNacks(pitEntry);
// this->rejectPendingInterest(pitEntry);
this->setExpiryTimer(pitEntry, interest.getInterestLifetime());

// to support either Nack or retain in the same strategy, use a strategy parameter (#3868)
}
}

bool
supportsNewNexthop() const
{
return true;
}

void
afterNewNexthop(const shared_ptr<pit::Entry>& pitEntry)
{
const fib::Entry& fibEntry = fib.lookup(pitEntry);
if (fibEntry_has_usable_nexthops) {
forward_to_these_nexthops();
} else if (pitEntry_has_existing_out_records) {
// do nothing
}
}
};

(1-1/2)