From 92e907ff4f07ca95eab4e1bba97cf1eb1f5a4ecd Mon Sep 17 00:00:00 2001 From: Pedro Marques Date: Sun, 17 May 2015 05:53:14 +0000 Subject: [PATCH] Use a template to compare STL vectors; make sure that Specs have comparisson functions. Closes-bug: #1455989 Change-Id: Ifc79aadd854b31e17a21a901615f397560211f5d --- src/base/util.h | 31 +++++++++++++------ src/bgp/bgp_attr.cc | 75 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 89 insertions(+), 17 deletions(-) diff --git a/src/base/util.h b/src/base/util.h index ffdf6527e40..63c004fbd0b 100644 --- a/src/base/util.h +++ b/src/base/util.h @@ -74,15 +74,28 @@ static ModuleInitializer TOKENPASTE2(init_, __LINE__)(Func); } while(0); // Compare sorted vectors of pointers. -#define KEY_COMPARE_VECTOR_PTRS(T, x, y) \ - do { \ - KEY_COMPARE((x).size(), (y).size()); \ - std::vector::const_iterator __ix, __iy; \ - for (__ix = (x).begin(), __iy = (y).begin(); \ - __ix < x.end(); ++__ix, ++__iy) { \ - KEY_COMPARE(**__ix, **__iy); \ - } \ - } while (0) +template +int STLSortedCompare(InputIterator first1, InputIterator last1, + InputIterator first2, InputIterator last2, + CompareOp op) { + InputIterator iter1 = first1; + InputIterator iter2 = first2; + while (iter1 != last1 && iter2 != last2) { + int result = op(*iter1, *iter2); + if (result != 0) { + return result; + } + ++iter1; + ++iter2; + } + if (iter1 != last1) { + return 1; + } + if (iter2 != last2) { + return -1; + } + return 0; +} template void STLDeleteValues(Container *container) { diff --git a/src/bgp/bgp_attr.cc b/src/bgp/bgp_attr.cc index f32f4e1660d..22322d5f631 100644 --- a/src/bgp/bgp_attr.cc +++ b/src/bgp/bgp_attr.cc @@ -323,10 +323,24 @@ void EdgeDiscoverySpec::Edge::SetLabels( labels.push_back(last_label); } +struct EdgeDiscoverySpecEdgeCompare { + int operator()(const EdgeDiscoverySpec::Edge *lhs, + const EdgeDiscoverySpec::Edge *rhs) const { + KEY_COMPARE(lhs->address, rhs->address); + KEY_COMPARE(lhs->labels, rhs->labels); + return 0; + } +}; + int EdgeDiscoverySpec::CompareTo(const BgpAttribute &rhs_attr) const { int ret = BgpAttribute::CompareTo(rhs_attr); if (ret != 0) return ret; - return 0; + const EdgeDiscoverySpec &rhs = + static_cast(rhs_attr); + ret = STLSortedCompare(edge_list.begin(), edge_list.end(), + rhs.edge_list.begin(), rhs.edge_list.end(), + EdgeDiscoverySpecEdgeCompare()); + return ret; } void EdgeDiscoverySpec::ToCanonical(BgpAttr *attr) { @@ -381,9 +395,19 @@ EdgeDiscovery::~EdgeDiscovery() { STLDeleteValues(&edge_list); } +struct EdgeDiscoveryEdgeCompare { + int operator()(const EdgeDiscovery::Edge *lhs, + const EdgeDiscovery::Edge *rhs) const { + KEY_COMPARE(*lhs, *rhs); + return 0; + } +}; + int EdgeDiscovery::CompareTo(const EdgeDiscovery &rhs) const { - KEY_COMPARE_VECTOR_PTRS(Edge, edge_list, rhs.edge_list); - return 0; + int result = STLSortedCompare(edge_list.begin(), edge_list.end(), + rhs.edge_list.begin(), rhs.edge_list.end(), + EdgeDiscoveryEdgeCompare()); + return result; } void EdgeDiscovery::Remove() { @@ -436,10 +460,26 @@ void EdgeForwardingSpec::Edge::SetOutboundIp4Address(Ip4Address addr) { outbound_address.begin()); } +struct EdgeForwardingSpecEdgeCompare { + int operator()(const EdgeForwardingSpec::Edge *lhs, + const EdgeForwardingSpec::Edge *rhs) const { + KEY_COMPARE(lhs->inbound_address, rhs->inbound_address); + KEY_COMPARE(lhs->outbound_address, rhs->outbound_address); + KEY_COMPARE(lhs->inbound_label, rhs->inbound_label); + KEY_COMPARE(lhs->outbound_label, rhs->outbound_label); + return 0; + } +}; + int EdgeForwardingSpec::CompareTo(const BgpAttribute &rhs_attr) const { int ret = BgpAttribute::CompareTo(rhs_attr); if (ret != 0) return ret; - return 0; + const EdgeForwardingSpec &rhs = + static_cast(rhs_attr); + ret = STLSortedCompare(edge_list.begin(), edge_list.end(), + rhs.edge_list.begin(), rhs.edge_list.end(), + EdgeForwardingSpecEdgeCompare()); + return ret; } void EdgeForwardingSpec::ToCanonical(BgpAttr *attr) { @@ -496,9 +536,19 @@ EdgeForwarding::~EdgeForwarding() { STLDeleteValues(&edge_list); } +struct EdgeForwardingEdgeCompare { + int operator()(const EdgeForwarding::Edge *lhs, + const EdgeForwarding::Edge *rhs) const { + KEY_COMPARE(*lhs, *rhs); + return 0; + } +}; + int EdgeForwarding::CompareTo(const EdgeForwarding &rhs) const { - KEY_COMPARE_VECTOR_PTRS(Edge, edge_list, rhs.edge_list); - return 0; + int result = STLSortedCompare(edge_list.begin(), edge_list.end(), + rhs.edge_list.begin(), rhs.edge_list.end(), + EdgeForwardingEdgeCompare()); + return result; } void EdgeForwarding::Remove() { @@ -555,10 +605,19 @@ BgpOList::~BgpOList() { STLDeleteValues(&elements); } +struct BgpOListElementCompare { + int operator()(const BgpOListElem *lhs, const BgpOListElem *rhs) const { + KEY_COMPARE(*lhs, *rhs); + return 0; + } +}; + int BgpOList::CompareTo(const BgpOList &rhs) const { KEY_COMPARE(olist().subcode, rhs.olist().subcode); - KEY_COMPARE_VECTOR_PTRS(BgpOListElem, elements, rhs.elements); - return 0; + int result = STLSortedCompare(elements.begin(), elements.end(), + rhs.elements.begin(), rhs.elements.end(), + BgpOListElementCompare()); + return result; } void BgpOList::Remove() {