8000 less branching in comparison functions · cloud-coders/arangodb@d0845f0 · GitHub
[go: up one dir, main page]

Skip to content

Commit d0845f0

Browse files
committed
less branching in comparison functions
1 parent 46f4e3b commit d0845f0

File tree

5 files changed

+83
-145
lines changed

5 files changed

+83
-145
lines changed

arangod/SkipLists/skiplistIndex.cpp

Lines changed: 16 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -73,30 +73,14 @@ static int CompareKeyElement (TRI_shaped_json_t const* left,
7373

7474
auto rightSubobjects = SkiplistIndex_Subobjects(right);
7575

76-
int result = TRI_CompareShapeTypes(nullptr,
77-
nullptr,
78-
left,
79-
shaper,
80-
right->_document->getShapedJsonPtr(),
81-
&rightSubobjects[rightPosition],
82-
nullptr,
83-
shaper);
84-
85-
// ...........................................................................
86-
// In the above function CompareShapeTypes we use strcmp which may
87-
// return an integer greater than 1 or less than -1. From this
88-
// function we only need to know whether we have equality (0), less
89-
// than (-1) or greater than (1)
90-
// ...........................................................................
91-
92-
if (result < 0) {
93-
result = -1;
94-
}
95-
else if (result > 0) {
96-
result = 1;
97-
}
98-
99-
return result;
76+
return TRI_CompareShapeTypes(nullptr,
77+
nullptr,
78+
left,
79+
shaper,
80+
right->_document->getShapedJsonPtr(),
81+
&rightSubobjects[rightPosition],
82+
nullptr,
83+
shaper);
10084
}
10185

10286
////////////////////////////////////////////////////////////////////////////////
@@ -114,30 +98,14 @@ static int CompareElementElement (TRI_skiplist_index_element_t const* left,
11498
auto leftSubobjects = SkiplistIndex_Subobjects(left);
11599
auto rightSubobjects = SkiplistIndex_Subobjects(right);
116100

117-
int result = TRI_CompareShapeTypes(left->_document->getShapedJsonPtr(),
118-
&leftSubobjects[leftPosition],
119-
nullptr,
120-
shaper,
121-
right->_document->getShapedJsonPtr(),
122-
&rightSubobjects[rightPosition],
123-
nullptr,
124-
shaper);
125-
126-
// ...........................................................................
127-
// In the above function CompareShapeTypes we use strcmp which may
128-
// return an integer greater than 1 or less than -1. From this
129-
// function we only need to know whether we have equality (0), less
130-
// than (-1) or greater than (1)
131-
// ...........................................................................
132-
133-
if (result < 0) {
134-
return -1;
135-
}
136-
else if (result > 0) {
137-
return 1;
138-
}
139-
140-
return 0;
101+
return TRI_CompareShapeTypes(left->_document->getShapedJsonPtr(),
102+
&leftSubobjects[leftPosition],
103+
nullptr,
104+
shaper,
105+
right->_document->getShapedJsonPtr(),
106+
&rightSubobjects[rightPosition],
107+
nullptr,
108+
shaper);
141109
}
142110

143111
////////////////////////////////////////////////////////////////////////////////

arangod/VocBase/voc-shaper.cpp

Lines changed: 9 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,22 +1582,10 @@ int TRI_CompareShapeTypes (char const* leftDocument,
15821582
void TRI_InspectShapedSub (TRI_shaped_sub_t const* element,
15831583
char const* shapedJson,
15841584
TRI_shaped_json_t& shaped) {
1585-
if (element->_sid == BasicShapes::TRI_SHAPE_SID_NULL) {
1585+
if (element->_sid <= BasicShapes::TRI_SHAPE_SID_SHORT_STRING) {
15861586
shaped._data.data = (char*) &element->_value._data;
1587-
shaped._data.length = 0;
1588-
}
1589-
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_BOOLEAN) {
1590-
shaped._data.data = (char*) &element->_value._data;
1591-
shaped._data.length = sizeof(TRI_shape_boolean_t);
1592-
}
1593-
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_NUMBER) {
1594-
shaped._data.data = (char*) &element->_value._data;
1595-
shaped._data.length = sizeof(TRI_shape_number_t);
1596-
}
1597-
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_SHORT_STRING) {
1598-
shaped._data.data = (char*) &element->_value._data;
1599-
shaped._data.length = sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT;
1600-
}
1587+
shaped._data.length = BasicShapes::TypeLengths[element->_sid];
1588+
}
16011589
else {
16021590
shaped._data.data = const_cast<char*>(shapedJson) + element->_value._position._offset; // ONLY IN INDEX
16031591
shaped._data.length = element->_value._position._length;
@@ -1608,22 +1596,10 @@ void TRI_InspectShapedSub (TRI_shaped_sub_t const* element,
16081596
TRI_doc_mptr_t const* mptr,
16091597
char const*& ptr,
16101598
size_t& length) {
1611-
if (element->_sid == BasicShapes::TRI_SHAPE_SID_NULL) {
1612-
ptr = (char const*) &element->_value._data;
1613-
length = 0;
1614-
}
1615-
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_BOOLEAN) {
1599+
if (element->_sid <= BasicShapes::TRI_SHAPE_SID_SHORT_STRING) {
16161600
ptr = (char const*) &element->_value._data;
1617-
length = sizeof(TRI_shape_boolean_t);
1618-
}
1619-
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_NUMBER) {
1620-
ptr = (char const*) &element->_value._data;
1621-
length = sizeof(TRI_shape_number_t);
1622-
}
1623-
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_SHORT_STRING) {
1624-
ptr = (char const*) &element->_value._data;
1625-
length = sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT;
1626-
}
1601+
length = BasicShapes::TypeLengths[element->_sid];
1602+
}
16271603
else {
16281604
ptr = mptr->getShapedJsonPtr() + element->_value._position._offset; // ONLY IN INDEX
16291605
length = element->_value._position._length;
@@ -1635,17 +1611,9 @@ void TRI_FillShapedSub (TRI_shaped_sub_t* element,
16351611
char const* ptr) {
16361612
element->_sid = shapedObject->_sid;
16371613

1638-
if (element->_sid == BasicShapes::TRI_SHAPE_SID_NULL) {
1639-
}
1640-
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_BOOLEAN) {
1641-
memcpy((char*) &element->_value._data, shapedObject->_data.data, sizeof(TRI_shape_boolean_t));
1642-
}
1643-
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_NUMBER) {
1644-
memcpy((char*) &element->_value._data, shapedObject->_data.data, sizeof(TRI_shape_number_t));
1645-
}
1646-
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_SHORT_STRING) {
1647-
memcpy((char*) &element->_value._data, shapedObject->_data.data, sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT);
1648-
}
1614+
if (element->_sid <= BasicShapes::TRI_SHAPE_SID_SHORT_STRING) {
1615+
memcpy((char*) &element->_value._data, shapedObject->_data.data, BasicShapes::TypeLengths[element->_sid]);
1616+
}
16491617
else {
16501618
element->_value._position._length = shapedObject->_data.length;
16511619
element->_value._position._offset = static_cast<uint32_t>(((char const*) shapedObject->_data.data) - ptr);

arangod/VocBase/voc-shaper.h

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -138,22 +138,21 @@ int TRI_CompareShapeTypes (char const* leftDocument,
138138
/// @brief extracts the shape identifier pointer from a marker
139139
////////////////////////////////////////////////////////////////////////////////
140140

141-
static inline void TRI_EXTRACT_SHAPE_IDENTIFIER_MARKER(
142-
TRI_shape_sid_t& dst,
143-
void const* src) {
141+
static inline void TRI_EXTRACT_SHAPE_IDENTIFIER_MARKER (TRI_shape_sid_t& dst,
142+
void const* src) {
144143

145-
TRI_df_marker_t const* marker = static_cast<TRI_df_marker_t const*>(src);
144+
auto type = static_cast<TRI_df_marker_t const*>(src)->_type;
146145

147-
if (marker->_type == TRI_DOC_MARKER_KEY_DOCUMENT) {
146+
if (type == TRI_DOC_MARKER_KEY_DOCUMENT) {
148147
dst = static_cast<TRI_doc_document_key_marker_t const*>(src)->_shape;
149148
}
150-
else if (marker->_type == TRI_DOC_MARKER_KEY_EDGE) {
149+
else if (type == TRI_DOC_MARKER_KEY_EDGE) {
151150
dst = static_cast<TRI_doc_edge_key_marker_t const*>(src)->base._shape;
152151
}
153-
else if (marker->_type == TRI_WAL_MARKER_DOCUMENT) {
152+
else if (type == TRI_WAL_MARKER_DOCUMENT) {
154153
dst = static_cast<triagens::wal::document_marker_t const*>(src)->_shape;
155154
}
156-
else if (marker->_type == TRI_WAL_MARKER_EDGE) {
155+
else if (type == TRI_WAL_MARKER_EDGE) {
157156
dst = static_cast<triagens::wal::edge_marker_t const*>(src)->_shape;
158157
}
159158
else {
@@ -167,32 +166,24 @@ static inline void TRI_EXTRACT_SHAPE_IDENTIFIER_MARKER(
167166

168167
static inline void TRI_EXTRACT_SHAPED_JSON_MARKER (TRI_shaped_json_t& dst,
169168
void const* src) {
170-
if (static_cast<TRI_df_marker_t const*>(src)->_type ==
171-
TRI_DOC_MARKER_KEY_DOCUMENT) {
172-
dst._sid = static_cast<TRI_doc_document_key_marker_t const*>(src)->_shape;
173-
dst._data.length = static_cast<TRI_df_marker_t const*>(src)->_size
174-
- static_cast<TRI_doc_document_key_marker_t const*>(src)->_offsetJson;
175-
dst._data.data = const_cast<char*>(static_cast<char const*>(src))
176-
+ static_cast<TRI_doc_document_key_marker_t const*>(src)->_offsetJson;
177-
}
178-
else if (static_cast<TRI_df_marker_t const*>(src)->_type ==
179-
TRI_DOC_MARKER_KEY_EDGE) {
169+
auto type = static_cast<TRI_df_marker_t const*>(src)->_type;
170+
171+
if (type == TRI_DOC_MARKER_KEY_DOCUMENT ||
172+
type == TRI_DOC_MARKER_KEY_EDGE) {
180173
dst._sid = static_cast<TRI_doc_document_key_marker_t const*>(src)->_shape;
181174
dst._data.length = static_cast<TRI_df_marker_t const*>(src)->_size
182175
- static_cast<TRI_doc_document_key_marker_t const*>(src)->_offsetJson;
183176
dst._data.data = const_cast<char*>(static_cast<char const*>(src))
184177
+ static_cast<TRI_doc_document_key_marker_t const*>(src)->_offsetJson;
185178
}
186-
else if (static_cast<TRI_df_marker_t const*>(src)->_type ==
187-
TRI_WAL_MARKER_DOCUMENT) {
179+
else if (type == TRI_WAL_MARKER_DOCUMENT) {
188180
dst._sid = static_cast<triagens::wal::document_marker_t const*>(src)->_shape;
189181
dst._data.length = static_cast<TRI_df_marker_t const*>(src)->_size
190182
- static_cast<triagens::wal::document_marker_t const*>(src)->_offsetJson;
191183
dst._data.data = const_cast<char*>(static_cast<char const*>(src))
192184
+ static_cast<triagens::wal::document_marker_t const*>(src)->_offsetJson;
193185
}
194-
else if (static_cast<TRI_df_marker_t const*>(src)->_type ==
195-
TRI_WAL_MARKER_EDGE) {
186+
else if (type == TRI_WAL_MARKER_EDGE) {
196187
dst._sid = static_cast<triagens::wal::edge_marker_t const*>(src)->_shape;
197188
dst._data.length = static_cast<TRI_df_marker_t const*>(src)->_size
198189
- static_cast<triagens::wal::edge_marker_t const*>(src)->_offsetJson;

lib/ShapedJson/json-shaper.cpp

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,33 @@ TRI_shape_t const BasicShapes::_shapeList = {
9292
TRI_SHAPE_SIZE_VARIABLE
9393
};
9494

95+
TRI_shape_t const* BasicShapes::ShapeAddresses[7] = {
96+
nullptr,
97+
&BasicShapes::_shapeNull,
98+
&BasicShapes::_shapeBoolean,
99+
&BasicShapes::_shapeNumber,
100+
&BasicShapes::_shapeShortString,
101+
&BasicShapes::_shapeLongString,
102+
&BasicShapes::_shapeList
103+
};
104+
105+
////////////////////////////////////////////////////////////////////////////////
106+
/// @brief static const length information for basic shape types
107+
////////////////////////////////////////////////////////////////////////////////
108+
109+
uint32_t const BasicShapes::TypeLengths[5] = {
110+
0, // not used
111+
0, // null
112+
sizeof(TRI_shape_boolean_t),
113+
sizeof(TRI_shape_number_t),
114+
sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT
115+
};
116+
117+
static_assert(BasicShapes::TRI_SHAPE_SID_NULL == 1, "invalid shape id for null shape");
118+
static_assert(BasicShapes::TRI_SHAPE_SID_BOOLEAN == 2, "invalid shape id for boolean shape");
119+
static_assert(BasicShapes::TRI_SHAPE_SID_NUMBER == 3, "invalid shape id for number shape");
120+
static_assert(BasicShapes::TRI_SHAPE_SID_SHORT_STRING == 4, "invalid shape id for short string shape");
121+
95122
// -----------------------------------------------------------------------------
96123
// --SECTION-- private functions
97124
// -----------------------------------------------------------------------------
@@ -420,30 +447,11 @@ void TRI_FreeShaper (TRI_shaper_t* shaper) {
420447
////////////////////////////////////////////////////////////////////////////////
421448

422449
TRI_shape_t const* TRI_LookupSidBasicShapeShaper (TRI_shape_sid_t sid) {
423-
if (sid >= TRI_FirstCustomShapeIdShaper() || sid == 0) {
450+
if (sid > BasicShapes::TRI_SHAPE_SID_LIST) {
424451
return nullptr;
425452
}
426453

427-
if (sid == BasicShapes::TRI_SHAPE_SID_NULL) {
428-
return &BasicShapes::_shapeNull;
429-
}
430-
else if (sid == BasicShapes::TRI_SHAPE_SID_BOOLEAN) {
431-
return &BasicShapes::_shapeBoolean;
432-
}
433-
else if (sid == BasicShapes::TRI_SHAPE_SID_NUMBER) {
434-
return &BasicShapes::_shapeNumber;
435-
}
436-
else if (sid == BasicShapes::TRI_SHAPE_SID_SHORT_STRING) {
437-
return &BasicShapes::_shapeShortString;
438-
}
439-
else if (sid == BasicShapes::TRI_SHAPE_SID_LONG_STRING) {
440-
return &BasicShapes::_shapeLongString;
441-
}
442-
else if (sid == BasicShapes::TRI_SHAPE_SID_LIST) {
443-
return &BasicShapes::_shapeList;
444-
}
445-
446-
return nullptr;
454+
return BasicShapes::ShapeAddresses[sid];
447455
}
448456

449457
////////////////////////////////////////////////////////////////////////////////

lib/ShapedJson/json-shaper.h

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,22 @@
4949
////////////////////////////////////////////////////////////////////////////////
5050

5151
struct BasicShapes {
52-
static TRI_shape_pid_t const TRI_SHAPE_SID_NULL;
53-
static TRI_shape_pid_t const TRI_SHAPE_SID_BOOLEAN;
54-
static TRI_shape_pid_t const TRI_SHAPE_SID_NUMBER;
55-
static TRI_shape_pid_t const TRI_SHAPE_SID_SHORT_STRING;
56-
static TRI_shape_pid_t const TRI_SHAPE_SID_LONG_STRING;
57-
static TRI_shape_pid_t const TRI_SHAPE_SID_LIST;
58-
59-
static TRI_shape_t const _shapeNull;
60-
static TRI_shape_t const _shapeBoolean;
61-
static TRI_shape_t const _shapeNumber;
62-
static TRI_shape_t const _shapeShortString;
63-
static TRI_shape_t const _shapeLongString;
64-
static TRI_shape_t const _shapeList;
52+
static TRI_shape_pid_t const TRI_SHAPE_SID_NULL;
53+
static TRI_shape_pid_t const TRI_SHAPE_SID_BOOLEAN;
54+
static TRI_shape_pid_t const TRI_SHAPE_SID_NUMBER;
55+
static TRI_shape_pid_t const TRI_SHAPE_SID_SHORT_STRING;
56+
static TRI_shape_pid_t const TRI_SHAPE_SID_LONG_STRING;
57+
static TRI_shape_pid_t const TRI_SHAPE_SID_LIST;
58+
59+
static TRI_shape_t const _shapeNull;
60+
static TRI_shape_t const _shapeBoolean;
61+
static TRI_shape_t const _shapeNumber;
62+
static TRI_shape_t const _shapeShortString;
63+
static TRI_shape_t const _shapeLongString;
64+
static TRI_shape_t const _shapeList;
65+
66+
static uint32_t const TypeLengths[5];
67+
static TRI_shape_t const* ShapeAddresses[7];
6568
};
6669

6770
// -----------------------------------------------------------------------------

0 commit comments

Comments
 (0)
0