Skip to content

Commit 8311bd3

Browse files
committed
Use local derivedFields for offset/mask calculations and other meta processing, simplifies the logic and indexing
Signed-off-by: Adam Glustein <adam.glustein@point72.com>
1 parent 170bb72 commit 8311bd3

1 file changed

Lines changed: 16 additions & 14 deletions

File tree

cpp/csp/engine/Struct.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ StructMeta::StructMeta( const std::string & name, Fields fields, bool isStrict,
8989
else
9090
m_fieldnames = std::move( fieldnames );
9191

92+
std::vector<StructFieldPtr> derivedFields; // easier to store this for pre-processing and only append derived fields to m_fields at the end
9293
for( auto & derivedField : fields )
9394
{
9495
auto rv = m_fieldMap.emplace( derivedField -> fieldname().c_str(), derivedField );
@@ -117,28 +118,28 @@ StructMeta::StructMeta( const std::string & name, Fields fields, bool isStrict,
117118
rv.first -> second = derivedField; // field map
118119
}
119120
else
120-
m_fields.push_back( derivedField );
121+
derivedFields.push_back( derivedField );
121122
}
122123

123124
size_t baseSize = m_base ? m_base -> size() : 0;
124125
size_t offset = baseSize;
125126
m_basePadding = 0;
126127

127128
//align to first field's alignment if there are derived fields remaining
128-
if( m_fields.size() > m_firstPartialField && ( offset % m_fields[ m_firstPartialField ] -> alignment() != 0 ) )
129-
m_basePadding = m_fields[ m_firstPartialField ] -> alignment() - offset % m_fields[ m_firstPartialField ] -> alignment();
129+
if( !derivedFields.empty() && ( offset % derivedFields[ 0 ] -> alignment() != 0 ) )
130+
m_basePadding = derivedFields[ 0 ] -> alignment() - offset % derivedFields[ 0 ] -> alignment();
130131

131132
offset += m_basePadding;
132-
if( m_fields.size() > m_firstPartialField )
133-
CSP_ASSERT( ( offset % m_fields[ m_firstPartialField ] -> alignment() ) == 0 );
133+
if( !derivedFields.empty() )
134+
CSP_ASSERT( ( offset % derivedFields[ 0 ] -> alignment() ) == 0 );
134135

135136
m_partialStart = offset;
136137
m_nativeStart = m_partialStart;
137138
m_firstNativePartialField = m_firstPartialField;
138139

139-
for( size_t idx = m_firstPartialField; idx < m_fields.size(); ++idx )
140+
for( size_t idx = 0; idx < derivedFields.size(); ++idx )
140141
{
141-
auto & f = m_fields[ idx ];
142+
auto & f = derivedFields[ idx ];
142143
if( offset % f -> alignment() != 0 )
143144
offset += f -> alignment() - offset % f -> alignment();
144145

@@ -151,7 +152,7 @@ StructMeta::StructMeta( const std::string & name, Fields fields, bool isStrict,
151152
if( !f -> isNative() )
152153
{
153154
m_nativeStart = offset;
154-
m_firstNativePartialField = idx + 1;
155+
m_firstNativePartialField += 1;
155156
}
156157
}
157158

@@ -160,8 +161,8 @@ StructMeta::StructMeta( const std::string & name, Fields fields, bool isStrict,
160161
// setup masking bits for the remaining derived (partial) fields
161162
// note that this is done after the override dedup above so that overridden fields don't consume mask bits.
162163
//NOTE we can be more efficient by sticking masks into any potential alignment gaps, dont want to spend time on it
163-
size_t optionalFieldCount = std::count_if( m_fields.begin() + m_firstPartialField, m_fields.end(), []( const auto & f ) { return f -> isOptional(); } );
164-
size_t partialFieldCount = m_fields.size() - m_firstPartialField;
164+
size_t optionalFieldCount = std::count_if( derivedFields.begin(), derivedFields.end(), []( const auto & f ) { return f -> isOptional(); } );
165+
size_t partialFieldCount = derivedFields.size();
165166

166167
m_maskSize = partialFieldCount > 0 ? 1 + ( ( partialFieldCount + optionalFieldCount - 1 ) / 8 ) : 0;
167168
m_size = offset + m_maskSize;
@@ -177,9 +178,8 @@ StructMeta::StructMeta( const std::string & name, Fields fields, bool isStrict,
177178
// Set optional fields first so that their 2-bits never cross a byte boundary
178179
// Put both the set bits and none bits in the same vector to avoid fragmentation
179180
m_optionalFieldsBitMasks.resize( 2 * m_maskSize );
180-
for( size_t i = m_firstPartialField; i < m_fields.size(); ++i )
181+
for( auto & f : derivedFields )
181182
{
182-
auto & f = m_fields[ i ];
183183
if( f -> isOptional() )
184184
{
185185
f -> setMaskOffset( maskLoc, maskBit );
@@ -193,9 +193,8 @@ StructMeta::StructMeta( const std::string & name, Fields fields, bool isStrict,
193193
}
194194
}
195195

196-
for( size_t i = m_firstPartialField; i < m_fields.size(); ++i )
196+
for( auto & f : derivedFields )
197197
{
198-
auto & f = m_fields[ i ];
199198
if( !f -> isOptional() )
200199
{
201200
f -> setMaskOffset( maskLoc, maskBit );
@@ -206,6 +205,9 @@ StructMeta::StructMeta( const std::string & name, Fields fields, bool isStrict,
206205
}
207206
}
208207
}
208+
209+
// append derived fields to m_fields after all processing is done
210+
m_fields.insert( m_fields.end(), derivedFields.begin(), derivedFields.end() );
209211
}
210212

211213
StructMeta::~StructMeta()

0 commit comments

Comments
 (0)