From 1c1e1b1fb9bf9ca1c874beded0a0b97f8e98f7a4 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 28 Feb 2014 14:12:35 +0400 Subject: [PATCH] GDTR: much faster type signature computation --- libuavcan/src/global_data_type_registry.cpp | 49 ++++++++------------ libuavcan/test/global_data_type_registry.cpp | 8 ++++ 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/libuavcan/src/global_data_type_registry.cpp b/libuavcan/src/global_data_type_registry.cpp index 734f691367..18a26c423e 100644 --- a/libuavcan/src/global_data_type_registry.cpp +++ b/libuavcan/src/global_data_type_registry.cpp @@ -141,44 +141,35 @@ DataTypeSignature GlobalDataTypeRegistry::computeAggregateSignature(DataTypeKind return DataTypeSignature(); } + int prev_dtid = -1; DataTypeSignature signature; bool signature_initialized = false; - - for (int id = 0; id <= DataTypeDescriptor::MaxDataTypeID; id++) + Entry* p = list->get(); + while (p) { - if (!inout_id_mask[id]) - continue; + const DataTypeDescriptor& desc = p->descriptor; - // TODO: do it faster - no need to traverse the list on each iteration - const DataTypeDescriptor* desc = NULL; - { - Entry* p = list->get(); - while (p) - { - if (p->descriptor.match(kind, id)) - { - desc = &p->descriptor; - break; - } - p = p->getNextListNode(); - } - } - - if (desc) + if (inout_id_mask[desc.getID()]) { if (signature_initialized) - { - signature.extend(desc->getSignature()); - } + signature.extend(desc.getSignature()); else - { - signature_initialized = true; - signature = DataTypeSignature(desc->getSignature()); - } + signature = DataTypeSignature(desc.getSignature()); + signature_initialized = true; } - else - inout_id_mask[id] = false; + + assert(prev_dtid < desc.getID()); // Making sure that list is ordered properly + prev_dtid++; + while (prev_dtid < desc.getID()) + inout_id_mask[prev_dtid++] = false; // Erasing bits for missing types + assert(prev_dtid == desc.getID()); + + p = p->getNextListNode(); } + prev_dtid++; + while (prev_dtid <= DataTypeDescriptor::MaxDataTypeID) + inout_id_mask[prev_dtid++] = false; + return signature; } diff --git a/libuavcan/test/global_data_type_registry.cpp b/libuavcan/test/global_data_type_registry.cpp index dbe12809c0..938136eee1 100644 --- a/libuavcan/test/global_data_type_registry.cpp +++ b/libuavcan/test/global_data_type_registry.cpp @@ -249,6 +249,14 @@ TEST(GlobalDataTypeRegistry, AggregateSignature) check_signature.extend(DataTypeB::getDataTypeSignature()); ASSERT_EQ(check_signature, sign); } + + // One + mask[1] = mask[43] = true; + sign = GlobalDataTypeRegistry::instance().computeAggregateSignature(uavcan::DataTypeKindService, mask); + ASSERT_TRUE(mask[43]); // DataTypeD + mask[43] = false; + ASSERT_FALSE(mask.any()); + ASSERT_EQ(DataTypeD::getDataTypeSignature(), sign); }