Task #2741
closedCreate proposal to redesign a more generic LSDB
100%
Description
Currently, the LSDB is implemented with multiple unique LSDB interaction methods for each LSA type.
This task should report where separate LSA methods can be combined into general methods.
Updated by Muktadir Chowdhury over 9 years ago
The following methods of LSDB class has been generalized(by templating): findLsa(), isLsaNew().
And, lsaCompareByKey() has been moved to lsa.hpp, and getKey() has been changed to normal member-function from a virtual function in the parent class of all LSAs'(also in lsa.hpp).
Updated by Muktadir Chowdhury over 9 years ago
- Status changed from New to Code review
- % Done changed from 0 to 80
Updated by Muktadir Chowdhury over 8 years ago
- Status changed from Code review to Feedback
Updated by Nicholas Gordon over 8 years ago
- Status changed from Feedback to Closed
Updated by Nicholas Gordon over 7 years ago
After looking over the code and the proposed changes, I have a few ideas about how to approach this generalization:
- All three methods to install an LSA of some type overlap in significant ways. In particular, the three functions all do:
- Checking that the LSA is new
- Writing various things to the log
- Checking that the LSA is not our own LSA, and only processing it if it is someone else's.
- Setting expiration times for the LSA.
- When updating an existing LSA, updating most of the fields.
I can suggest a few ways to make this more flexible, including something like:
- Declaring three virtual methods in the Lsa superclass,
install()
,remove()
, andoperator==
. The naive approach would be simply to compare the existing LSA to the one we're installing, sort of like this (in pseudocode):
if lsa.new()
lsa.install()
else
oldLsa = findOldLsa()
if lsa != oldLsa
oldLsa.remove()
lsa.install()
This doesn't really solve the problem of actually handling how each LSA mutates NLSR's state, but it does make the logic of processing each LSA simpler.
Alternately, the template specialization approach could be used to define case-wise, but I think in this situation it makes much more sense to use a class-based approach; what is the "sensible default" approach for install()
, remove()
, and operator==
for an arbitrary LSA?
- Creating a virtual constructor in the Lsa superclass that takes in an Nlsr object and creates an LSA representing the state of that Nlsr object. Then, the creation process could look something like:
template<LsaType> void
buildAndInstallOwnLsa() {
installLsa(LsaType(m_nlsr));
}
This would call that constructor using the NLSR object, and the virtual methods listed above would finish the job.
- The methods of add{Adj, Coordinate, Name}Lsa() all do the exact same thing, so that could be cleanly genericized without implementing behavior in the Lsa subclasses.
- The methods of does{Adj, Coordinate, Name}Lsa() can also be cleanly genericized like above.
- The methods of {adj, coordinate, name}LsaCompareByKey() can also be cleanly genericized.
- The methods of exprireOrRefresh{Adj, Coordinate, Name}Lsa are all exactly the same and can be condensed into one function, without even needing to template it. The object slicing problem doesn't apply here because the attributes needed in this class are all contained in the Lsa superclass.
There are several more triplets of methods that I could comment on, but I hope that at this point the strategy I'm suggesting is clear enough.
As a remark, it would be possible to encapsulate the "extra data" from each subclass into a tuple, and then then comparing the Lsas by atribute gets you equality comparison essentially for free.
Updated by Nicholas Gordon almost 7 years ago
- Blocks Task #4127: Rebuild the LSDB added