GDTR: much faster type signature computation

This commit is contained in:
Pavel Kirienko
2014-02-28 14:12:35 +04:00
parent 03cf4aa901
commit 1c1e1b1fb9
2 changed files with 28 additions and 29 deletions
+20 -29
View File
@@ -141,44 +141,35 @@ DataTypeSignature GlobalDataTypeRegistry::computeAggregateSignature(DataTypeKind
return DataTypeSignature(); return DataTypeSignature();
} }
int prev_dtid = -1;
DataTypeSignature signature; DataTypeSignature signature;
bool signature_initialized = false; bool signature_initialized = false;
Entry* p = list->get();
for (int id = 0; id <= DataTypeDescriptor::MaxDataTypeID; id++) while (p)
{ {
if (!inout_id_mask[id]) const DataTypeDescriptor& desc = p->descriptor;
continue;
// TODO: do it faster - no need to traverse the list on each iteration if (inout_id_mask[desc.getID()])
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 (signature_initialized) if (signature_initialized)
{ signature.extend(desc.getSignature());
signature.extend(desc->getSignature());
}
else else
{ signature = DataTypeSignature(desc.getSignature());
signature_initialized = true; signature_initialized = true;
signature = DataTypeSignature(desc->getSignature());
}
} }
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; return signature;
} }
@@ -249,6 +249,14 @@ TEST(GlobalDataTypeRegistry, AggregateSignature)
check_signature.extend(DataTypeB::getDataTypeSignature()); check_signature.extend(DataTypeB::getDataTypeSignature());
ASSERT_EQ(check_signature, sign); 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);
} }