1
0
Fork 0

Merge branch 'devel' of github.com:arangodb/arangodb into devel

This commit is contained in:
Frank Celler 2015-02-16 10:27:19 +01:00
commit cbb0b2f372
17 changed files with 495 additions and 602 deletions

View File

@ -63,11 +63,11 @@ static bool ExtractDoubleArray (TRI_shaper_t* shaper,
*missing = true;
return false;
}
else if (json._sid == TRI_LookupBasicSidShaper(TRI_SHAPE_NUMBER)) {
else if (json._sid == BasicShapes::TRI_SHAPE_SID_NUMBER) {
*result = * (double*) json._data.data;
return true;
}
else if (json._sid == TRI_LookupBasicSidShaper(TRI_SHAPE_NULL)) {
else if (json._sid == BasicShapes::TRI_SHAPE_SID_NULL) {
*missing = true;
return false;
}
@ -116,7 +116,7 @@ static bool ExtractDoubleList (TRI_shaper_t* shaper,
// latitude
ok = TRI_AtListShapedJson((const TRI_list_shape_t*) shape, &list, 0, &entry);
if (! ok || entry._sid != TRI_LookupBasicSidShaper(TRI_SHAPE_NUMBER)) {
if (! ok || entry._sid != BasicShapes::TRI_SHAPE_SID_NUMBER) {
return false;
}
@ -125,7 +125,7 @@ static bool ExtractDoubleList (TRI_shaper_t* shaper,
// longitude
ok = TRI_AtListShapedJson((const TRI_list_shape_t*) shape, &list, 1, &entry);
if (! ok || entry._sid != TRI_LookupBasicSidShaper(TRI_SHAPE_NUMBER)) {
if (! ok || entry._sid != BasicShapes::TRI_SHAPE_SID_NUMBER) {
return false;
}
@ -140,7 +140,7 @@ static bool ExtractDoubleList (TRI_shaper_t* shaper,
hom = (const TRI_homogeneous_list_shape_t*) shape;
if (hom->_sidEntry != TRI_LookupBasicSidShaper(TRI_SHAPE_NUMBER)) {
if (hom->_sidEntry != BasicShapes::TRI_SHAPE_SID_NUMBER) {
return false;
}
@ -177,7 +177,7 @@ static bool ExtractDoubleList (TRI_shaper_t* shaper,
hom = (const TRI_homogeneous_sized_list_shape_t*) shape;
if (hom->_sidEntry != TRI_LookupBasicSidShaper(TRI_SHAPE_NUMBER)) {
if (hom->_sidEntry != BasicShapes::TRI_SHAPE_SID_NUMBER) {
return false;
}
@ -240,25 +240,17 @@ static size_t MemoryGeoIndex (TRI_index_t const* idx) {
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* JsonGeo1Index (TRI_index_t const* idx) {
TRI_json_t* json;
TRI_json_t* fields;
TRI_shape_path_t const* path;
char const* location;
TRI_geo_index_t const* geo = (TRI_geo_index_t const*) idx;
TRI_document_collection_t* document = idx->_collection;
// convert location to string
path = document->getShaper()->lookupAttributePathByPid(document->getShaper(), geo->_location); // ONLY IN INDEX, PROTECTED by RUNTIME
char const* location = TRI_AttributeNameShapePid(document->getShaper(), geo->_location);
if (path == nullptr) {
if (location == nullptr) {
return nullptr;
}
location = TRI_NAME_SHAPE_PATH(path);
// create json
json = TRI_JsonIndex(TRI_CORE_MEM_ZONE, idx);
TRI_json_t* json = TRI_JsonIndex(TRI_CORE_MEM_ZONE, idx);
if (json == nullptr) {
return nullptr;
@ -272,7 +264,7 @@ static TRI_json_t* JsonGeo1Index (TRI_index_t const* idx) {
TRI_Insert3ObjectJson(TRI_CORE_MEM_ZONE, json, "ignoreNull", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, idx->_ignoreNull));
fields = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE);
TRI_json_t* fields = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE, 1);
TRI_PushBack3ArrayJson(TRI_CORE_MEM_ZONE, fields, TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, location, strlen(location)));
TRI_Insert3ObjectJson(TRI_CORE_MEM_ZONE, json, "fields", fields);
@ -284,35 +276,25 @@ static TRI_json_t* JsonGeo1Index (TRI_index_t const* idx) {
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* JsonGeo2Index (TRI_index_t const* idx) {
TRI_json_t* json;
TRI_json_t* fields;
TRI_shape_path_t const* path;
char const* latitude;
char const* longitude;
TRI_geo_index_t const* geo = (TRI_geo_index_t const*) idx;
TRI_document_collection_t* document = idx->_collection;
// convert latitude to string
path = document->getShaper()->lookupAttributePathByPid(document->getShaper(), geo->_latitude); // ONLY IN INDEX, PROTECTED by RUNTIME
char const* latitude = TRI_AttributeNameShapePid(document->getShaper(), geo->_latitude);
if (path == nullptr) {
if (latitude == nullptr) {
return nullptr;
}
latitude = TRI_NAME_SHAPE_PATH(path);
// convert longitude to string
path = document->getShaper()->lookupAttributePathByPid(document->getShaper(), geo->_longitude); // ONLY IN INDEX, PROTECTED by RUNTIME
char const* longitude = TRI_AttributeNameShapePid(document->getShaper(), geo->_longitude);
if (path == nullptr) {
if (longitude == nullptr) {
return nullptr;
}
longitude = TRI_NAME_SHAPE_PATH(path);
// create json
json = TRI_JsonIndex(TRI_CORE_MEM_ZONE, idx);
TRI_json_t* json = TRI_JsonIndex(TRI_CORE_MEM_ZONE, idx);
if (json == nullptr) {
return nullptr;
@ -324,7 +306,7 @@ static TRI_json_t* JsonGeo2Index (TRI_index_t const* idx) {
TRI_Insert3ObjectJson(TRI_CORE_MEM_ZONE, json, "ignoreNull", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, geo->base._ignoreNull));
fields = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE);
TRI_json_t* fields = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE, 2);
TRI_PushBack3ArrayJson(TRI_CORE_MEM_ZONE, fields, TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, latitude, strlen(latitude)));
TRI_PushBack3ArrayJson(TRI_CORE_MEM_ZONE, fields, TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, longitude, strlen(longitude)));
TRI_Insert3ObjectJson(TRI_CORE_MEM_ZONE, json, "fields", fields);

View File

@ -35,6 +35,7 @@
#include "Basics/fasthash.h"
#include "HashIndex/hash-index.h"
#include "VocBase/document-collection.h"
#include "VocBase/voc-shaper.h"
// -----------------------------------------------------------------------------
// --SECTION-- COMPARISON
@ -59,16 +60,16 @@ static bool IsEqualKeyElement (TRI_hash_array_multi_t const* array,
auto length = leftJson->_data.length;
if (length != rightSub->_length) {
char const* rightData;
size_t rightLength;
TRI_InspectShapedSub(rightSub, right->_document, rightData, rightLength);
if (length != rightLength) {
return false;
}
if (0 < length) {
char const* ptr = right->_document->getShapedJsonPtr() + rightSub->_offset; // ONLY IN INDEX
if (memcmp(leftJson->_data.data, ptr, length) != 0) {
return false;
}
if (length > 0 && memcmp(leftJson->_data.data, rightData, length) != 0) {
return false;
}
}
@ -98,12 +99,15 @@ static uint64_t HashKey (TRI_hash_array_multi_t const* array,
static uint64_t HashElement (TRI_hash_array_multi_t const* array,
TRI_hash_index_element_multi_t const* element) {
uint64_t hash = 0x0123456789abcdef;
char const* ptr = element->_document->getShapedJsonPtr(); // ONLY IN INDEX
for (size_t j = 0; j < array->_numFields; j++) {
char const* data;
size_t length;
TRI_InspectShapedSub(&element->_subObjects[j], element->_document, data, length);
// ignore the sid for hashing
// only hash the data block
hash = fasthash64(ptr + element->_subObjects[j]._offset, element->_subObjects[j]._length, hash);
hash = fasthash64(data, length, hash);
}
return hash;

View File

@ -34,6 +34,7 @@
#include "Basics/fasthash.h"
#include "HashIndex/hash-index.h"
#include "VocBase/document-collection.h"
#include "VocBase/voc-shaper.h"
// -----------------------------------------------------------------------------
// --SECTION-- COMPARISON
@ -73,16 +74,16 @@ static bool IsEqualKeyElement (TRI_hash_array_t const* array,
auto length = leftJson->_data.length;
if (length != rightSub->_length) {
char const* rightData;
size_t rightLength;
TRI_InspectShapedSub(rightSub, right->_document, rightData, rightLength);
if (length != rightLength) {
return false;
}
if (0 < length) {
char const* ptr = right->_document->getShapedJsonPtr() + rightSub->_offset; // ONLY IN INDEX
if (memcmp(leftJson->_data.data, ptr, length) != 0) {
return false;
}
if (length > 0 && memcmp(leftJson->_data.data, rightData, length) != 0) {
return false;
}
}
@ -114,11 +115,13 @@ static uint64_t HashElement (TRI_hash_array_t* array,
uint64_t hash = 0x0123456789abcdef;
for (size_t j = 0; j < array->_numFields; j++) {
// ignore the sid for hashing
char const* ptr = element->_document->getShapedJsonPtr() + element->_subObjects[j]._offset; // ONLY IN INDEX
char const* data;
size_t length;
TRI_InspectShapedSub(&element->_subObjects[j], element->_document, data, length);
// ignore the sid for hashing
// only hash the data block
hash = fasthash64(ptr, element->_subObjects[j]._length, hash);
hash = fasthash64(data, length, hash);
}
return hash;

View File

@ -76,9 +76,10 @@ static int FillIndexSearchValueByHashIndexElement (TRI_hash_index_t* hashIndex,
size_t const n = NumPaths(hashIndex);
for (size_t i = 0; i < n; ++i) {
key->_values[i]._sid = element->_subObjects[i]._sid;
key->_values[i]._data.length = element->_subObjects[i]._length;
key->_values[i]._data.data = const_cast<char*>(ptr + element->_subObjects[i]._offset);
auto sid = element->_subObjects[i]._sid;
key->_values[i]._sid = sid;
TRI_InspectShapedSub(&element->_subObjects[i], ptr, key->_values[i]);
}
return TRI_ERROR_NO_ERROR;
@ -140,11 +141,10 @@ static int HashIndexHelper (TRI_hash_index_t const* hashIndex,
// field not part of the object
if (acc == nullptr || acc->_resultSid == TRI_SHAPE_ILLEGAL) {
hashElement->_subObjects[j]._sid = TRI_LookupBasicSidShaper(TRI_SHAPE_NULL);
hashElement->_subObjects[j]._length = 0;
hashElement->_subObjects[j]._offset = 0;
hashElement->_subObjects[j]._sid = BasicShapes::TRI_SHAPE_SID_NULL;
res = TRI_ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING;
if (sparse) {
// no need to continue
return res;
@ -159,7 +159,7 @@ static int HashIndexHelper (TRI_hash_index_t const* hashIndex,
return TRI_ERROR_INTERNAL;
}
if (shapedObject._sid == TRI_LookupBasicSidShaper(TRI_SHAPE_NULL)) {
if (shapedObject._sid == BasicShapes::TRI_SHAPE_SID_NULL) {
res = TRI_ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING;
if (sparse) {
@ -167,10 +167,8 @@ static int HashIndexHelper (TRI_hash_index_t const* hashIndex,
return res;
}
}
hashElement->_subObjects[j]._sid = shapedObject._sid;
hashElement->_subObjects[j]._length = shapedObject._data.length;
hashElement->_subObjects[j]._offset = static_cast<uint32_t>(((char const*) shapedObject._data.data) - ptr);
TRI_FillShapedSub(&hashElement->_subObjects[j], &shapedObject, ptr);
}
return res;

View File

@ -1234,11 +1234,10 @@ static int SkiplistIndexHelper (TRI_skiplist_index_t const* skiplistIndex,
if (acc == nullptr || acc->_resultSid == TRI_SHAPE_ILLEGAL) {
// OK, the document does not contain the attributed needed by
// the index, are we sparse?
skiplistElement->_subObjects[j]._sid = TRI_LookupBasicSidShaper(TRI_SHAPE_NULL);
skiplistElement->_subObjects[j]._length = 0;
skiplistElement->_subObjects[j]._offset = 0;
skiplistElement->_subObjects[j]._sid = BasicShapes::TRI_SHAPE_SID_NULL;
res = TRI_ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING;
if (sparse) {
// no need to continue
return res;
@ -1255,8 +1254,9 @@ static int SkiplistIndexHelper (TRI_skiplist_index_t const* skiplistIndex,
return TRI_ERROR_INTERNAL;
}
if (shapedObject._sid == TRI_LookupBasicSidShaper(TRI_SHAPE_NULL)) {
if (shapedObject._sid == BasicShapes::TRI_SHAPE_SID_NULL) {
res = TRI_ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING;
if (sparse) {
// no need to continue
return res;
@ -1267,9 +1267,7 @@ static int SkiplistIndexHelper (TRI_skiplist_index_t const* skiplistIndex,
// Store the field
// .........................................................................
skiplistElement->_subObjects[j]._sid = shapedObject._sid;
skiplistElement->_subObjects[j]._length = shapedObject._data.length;
skiplistElement->_subObjects[j]._offset = static_cast<uint32_t>(((char const*) shapedObject._data.data) - ptr);
TRI_FillShapedSub(&skiplistElement->_subObjects[j], &shapedObject, ptr);
}
return res;

View File

@ -32,6 +32,9 @@
#include "Basics/Mutex.h"
#include "Basics/MutexLocker.h"
#include "Basics/ReadLocker.h"
#include "Basics/ReadWriteLock.h"
#include "Basics/WriteLocker.h"
#include "Basics/associative.h"
#include "Basics/hashes.h"
#include "Basics/locks.h"
@ -51,23 +54,23 @@
////////////////////////////////////////////////////////////////////////////////
typedef struct voc_shaper_s {
TRI_shaper_t base;
TRI_shaper_t base;
TRI_associative_synced_t _attributeNames;
TRI_associative_synced_t _attributeIds;
TRI_associative_synced_t _shapeDictionary;
TRI_associative_synced_t _shapeIds;
TRI_associative_synced_t _attributeNames;
TRI_associative_synced_t _attributeIds;
TRI_associative_synced_t _shapeDictionary;
TRI_associative_synced_t _shapeIds;
TRI_associative_pointer_t _accessors;
TRI_associative_pointer_t _accessors;
std::atomic<TRI_shape_aid_t> _nextAid;
std::atomic<TRI_shape_sid_t> _nextSid;
std::atomic<TRI_shape_aid_t> _nextAid;
std::atomic<TRI_shape_sid_t> _nextSid;
TRI_document_collection_t* _collection;
TRI_document_collection_t* _collection;
triagens::basics::Mutex _accessorLock;
triagens::basics::Mutex _shapeLock;
triagens::basics::Mutex _attributeLock;
triagens::basics::ReadWriteLock _accessorLock;
triagens::basics::Mutex _shapeLock;
triagens::basics::Mutex _attributeLock;
}
voc_shaper_t;
@ -86,7 +89,7 @@ static inline TRI_shape_aid_t GetAttributeId (void const* marker) {
if (p->_type == TRI_DF_MARKER_ATTRIBUTE) {
return reinterpret_cast<TRI_df_attribute_marker_t const*>(p)->_aid;
}
else if (p->_type == TRI_WAL_MARKER_ATTRIBUTE) {
if (p->_type == TRI_WAL_MARKER_ATTRIBUTE) {
return reinterpret_cast<triagens::wal::attribute_marker_t const*>(p)->_attributeId;
}
}
@ -105,7 +108,7 @@ static inline char const* GetAttributeName (void const* marker) {
if (p->_type == TRI_DF_MARKER_ATTRIBUTE) {
return reinterpret_cast<char const*>(p) + sizeof(TRI_df_attribute_marker_t);
}
else if (p->_type == TRI_WAL_MARKER_ATTRIBUTE) {
if (p->_type == TRI_WAL_MARKER_ATTRIBUTE) {
return reinterpret_cast<char const*>(p) + sizeof(triagens::wal::attribute_marker_t);
}
}
@ -119,7 +122,6 @@ static inline char const* GetAttributeName (void const* marker) {
static uint64_t HashKeyAttributeName (TRI_associative_synced_t* array, void const* key) {
char const* k = (char const*) key;
return TRI_FnvHashString(k);
}
@ -234,7 +236,6 @@ static TRI_shape_aid_t FindOrCreateAttributeByName (TRI_shaper_t* shaper,
static uint64_t HashKeyAttributeId (TRI_associative_synced_t* array, void const* key) {
TRI_shape_aid_t const* k = static_cast<TRI_shape_aid_t const*>(key);
return TRI_FnvHashPointer(k, sizeof(TRI_shape_aid_t));
}
@ -244,7 +245,6 @@ static uint64_t HashKeyAttributeId (TRI_associative_synced_t* array, void const*
static uint64_t HashElementAttributeId (TRI_associative_synced_t* array, void const* element) {
TRI_shape_aid_t aid = GetAttributeId(element);
return TRI_FnvHashPointer(&aid, sizeof(TRI_shape_aid_t));
}
@ -285,7 +285,6 @@ static uint64_t HashElementShape (TRI_associative_synced_t* array,
TRI_shape_t const* shape = static_cast<TRI_shape_t const*>(element);
TRI_ASSERT(shape != nullptr);
char const* s = reinterpret_cast<char const*>(shape);
return TRI_FnvHashPointer(s + sizeof(TRI_shape_sid_t), shape->_size - sizeof(TRI_shape_sid_t));
}
@ -409,7 +408,6 @@ static TRI_shape_t const* FindShape (TRI_shaper_t* shaper,
static uint64_t HashKeyShapeId (TRI_associative_synced_t* array,
void const* key) {
TRI_shape_sid_t const* k = static_cast<TRI_shape_sid_t const*>(key);
return TRI_FnvHashPointer(k, sizeof(TRI_shape_sid_t));
}
@ -421,7 +419,6 @@ static uint64_t HashElementShapeId (TRI_associative_synced_t* array,
void const* element) {
TRI_shape_t const* shape = static_cast<TRI_shape_t const*>(element);
TRI_ASSERT(shape != nullptr);
return TRI_FnvHashPointer(&shape->_sid, sizeof(TRI_shape_sid_t));
}
@ -897,26 +894,45 @@ int TRI_InsertAttributeVocShaper (TRI_shaper_t* s,
TRI_shape_access_t const* TRI_FindAccessorVocShaper (TRI_shaper_t* s,
TRI_shape_sid_t sid,
TRI_shape_pid_t pid) {
TRI_shape_access_t search;
search._sid = sid;
search._pid = pid;
TRI_shape_access_t search = { sid, pid, 0, nullptr };
voc_shaper_t* shaper = (voc_shaper_t*) s;
MUTEX_LOCKER(shaper->_accessorLock);
TRI_shape_access_t const* found;
{
READ_LOCKER(shaper->_accessorLock);
TRI_shape_access_t const* found = static_cast<TRI_shape_access_t const*>(TRI_LookupByElementAssociativePointer(&shaper->_accessors, &search));
found = static_cast<TRI_shape_access_t const*>(TRI_LookupByElementAssociativePointer(&shaper->_accessors, &search));
if (found == nullptr) {
found = TRI_ShapeAccessor(&shaper->base, sid, pid);
// TRI_ShapeAccessor can return a NULL pointer
if (found != nullptr) {
TRI_InsertElementAssociativePointer(&shaper->_accessors, const_cast<void*>(static_cast<void const*>(found)), true);
return found;
}
}
return found;
// not found... time for us to create the accessor ourselves!
TRI_shape_access_t* accessor = TRI_ShapeAccessor(&shaper->base, sid, pid);
// TRI_ShapeAccessor can return a NULL pointer
if (accessor == nullptr) {
return nullptr;
}
// acquire the write-lock and try to insert our own accessor
{
WRITE_LOCKER(shaper->_accessorLock);
found = static_cast<TRI_shape_access_t const*>(TRI_InsertElementAssociativePointer(&shaper->_accessors, const_cast<void*>(static_cast<void const*>(accessor)), false));
}
if (found != nullptr) {
// someone else inserted the same accessor in the period after we release the read-lock
// but before we acquired the write-lock
// this is ok, and we can return the concurrently built accessor now
TRI_FreeShapeAccessor(accessor);
return found;
}
return const_cast<TRI_shape_access_t const*>(accessor);
}
////////////////////////////////////////////////////////////////////////////////
@ -1158,8 +1174,7 @@ int TRI_CompareShapeTypes (char const* leftDocument,
// left is either a shaped json or a shaped sub object
if (leftDocument != nullptr) {
left._sid = leftObject->_sid;
left._data.length = leftObject->_length;
left._data.data = const_cast<char*>(leftDocument) + leftObject->_offset;
TRI_InspectShapedSub(leftObject, leftDocument, left);
}
else {
left = *leftShaped;
@ -1168,8 +1183,7 @@ int TRI_CompareShapeTypes (char const* leftDocument,
// right is either a shaped json or a shaped sub object
if (rightDocument != nullptr) {
right._sid = rightObject->_sid;
right._data.length = rightObject->_length;
right._data.data = const_cast<char*>(rightDocument) + rightObject->_offset;
TRI_InspectShapedSub(rightObject, rightDocument, right);
}
else {
right = *rightShaped;
@ -1563,6 +1577,79 @@ int TRI_CompareShapeTypes (char const* leftDocument,
return 0; //shut the vc++ up
}
void TRI_InspectShapedSub (TRI_shaped_sub_t const* element,
char const* shapedJson,
TRI_shaped_json_t& shaped) {
if (element->_sid == BasicShapes::TRI_SHAPE_SID_NULL) {
shaped._data.data = (char*) &element->_value._data;
shaped._data.length = 0;
}
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_BOOLEAN) {
shaped._data.data = (char*) &element->_value._data;
shaped._data.length = sizeof(TRI_shape_boolean_t);
}
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_NUMBER) {
shaped._data.data = (char*) &element->_value._data;
shaped._data.length = sizeof(TRI_shape_number_t);
}
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_SHORT_STRING) {
shaped._data.data = (char*) &element->_value._data;
shaped._data.length = sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT;
}
else {
shaped._data.data = const_cast<char*>(shapedJson) + element->_value._position._offset; // ONLY IN INDEX
shaped._data.length = element->_value._position._length;
}
}
void TRI_InspectShapedSub (TRI_shaped_sub_t const* element,
TRI_doc_mptr_t const* mptr,
char const*& ptr,
size_t& length) {
if (element->_sid == BasicShapes::TRI_SHAPE_SID_NULL) {
ptr = (char const*) &element->_value._data;
length = 0;
}
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_BOOLEAN) {
ptr = (char const*) &element->_value._data;
length = sizeof(TRI_shape_boolean_t);
}
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_NUMBER) {
ptr = (char const*) &element->_value._data;
length = sizeof(TRI_shape_number_t);
}
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_SHORT_STRING) {
ptr = (char const*) &element->_value._data;
length = sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT;
}
else {
ptr = mptr->getShapedJsonPtr() + element->_value._position._offset; // ONLY IN INDEX
length = element->_value._position._length;
}
}
void TRI_FillShapedSub (TRI_shaped_sub_t* element,
TRI_shaped_json_t const* shapedObject,
char const* ptr) {
element->_sid = shapedObject->_sid;
if (element->_sid == BasicShapes::TRI_SHAPE_SID_NULL) {
}
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_BOOLEAN) {
memcpy((char*) &element->_value._data, shapedObject->_data.data, sizeof(TRI_shape_boolean_t));
}
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_NUMBER) {
memcpy((char*) &element->_value._data, shapedObject->_data.data, sizeof(TRI_shape_number_t));
}
else if (element->_sid == BasicShapes::TRI_SHAPE_SID_SHORT_STRING) {
memcpy((char*) &element->_value._data, shapedObject->_data.data, sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT);
}
else {
element->_value._position._length = shapedObject->_data.length;
element->_value._position._offset = static_cast<uint32_t>(((char const*) shapedObject->_data.data) - ptr);
}
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

View File

@ -206,6 +206,19 @@ static inline void TRI_EXTRACT_SHAPED_JSON_MARKER (TRI_shaped_json_t& dst,
}
}
void TRI_InspectShapedSub (TRI_shaped_sub_t const*,
char const*,
TRI_shaped_json_t&);
void TRI_InspectShapedSub (TRI_shaped_sub_t const*,
TRI_doc_mptr_t const*,
char const*&,
size_t&);
void TRI_FillShapedSub (TRI_shaped_sub_t*,
TRI_shaped_json_t const*,
char const*);
#endif
// -----------------------------------------------------------------------------

View File

@ -56,7 +56,6 @@ void TRI_InitialiseC (int argc, char* argv[]) {
TRI_InitialiseRandom();
TRI_InitialiseProcess(argc, argv);
TRI_InitialiseSockets();
TRI_InitialiseShaper();
}
////////////////////////////////////////////////////////////////////////////////
@ -64,7 +63,6 @@ void TRI_InitialiseC (int argc, char* argv[]) {
////////////////////////////////////////////////////////////////////////////////
void TRI_ShutdownC () {
TRI_ShutdownShaper();
TRI_ShutdownSockets();
TRI_ShutdownProcess();
TRI_ShutdownRandom();

View File

@ -27,8 +27,9 @@
/// @author Copyright 2013-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "Basics/random.h"
#include "skip-list.h"
#include "Basics/random.h"
#include "Basics/Exceptions.h"
using namespace triagens::basics;
@ -50,9 +51,11 @@ static int randomHeight (void) {
while (true) { // will be left by return when the right height is found
uint32_t r = TRI_UInt32Random();
for (count = 32; count > 0; count--) {
if (0 != (r & 1UL) || height == TRI_SKIPLIST_MAX_HEIGHT) return height;
r = r >> 1;
height++;
if (0 != (r & 1UL) || height == TRI_SKIPLIST_MAX_HEIGHT) {
return height;
}
r = r >> 1;
height++;
}
}
}
@ -63,24 +66,32 @@ static int randomHeight (void) {
////////////////////////////////////////////////////////////////////////////////
SkipListNode* SkipList::allocNode (int height) {
SkipListNode* newNode = new SkipListNode();
newNode->_doc = nullptr;
if (0 == height) {
newNode->_height = randomHeight();
height = randomHeight();
}
else {
newNode->_height = height;
// allocate enough memory for skiplist node plus all the next nodes in one go
void* ptr = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(SkipListNode) + sizeof(SkipListNode*) * height, false);
if (ptr == nullptr) {
THROW_OUT_OF_MEMORY_ERROR();
}
SkipListNode* newNode;
try {
newNode->_next = new SkipListNode*[newNode->_height];
// use placement new
newNode = new(ptr) SkipListNode();
}
catch (...) {
delete newNode;
TRI_Free(TRI_UNKNOWN_MEM_ZONE, ptr);
throw;
}
newNode->_doc = nullptr;
newNode->_height = height;
newNode->_next = reinterpret_cast<SkipListNode**>(static_cast<char*>(ptr) + sizeof(SkipListNode));
for (int i = 0; i < newNode->_height; i++) {
newNode->_next[i] = nullptr;
}
@ -100,8 +111,11 @@ void SkipList::freeNode (SkipListNode* node) {
// update memory usage
_memoryUsed -= sizeof(SkipListNode) +
sizeof(SkipListNode*) * node->_height;
delete[] node->_next;
delete node;
// we have used placement new to construct the skiplist node,
// so now we have to manually call its dtor and free the underlying memory
node->~SkipListNode();
TRI_Free(TRI_UNKNOWN_MEM_ZONE, node);
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -225,17 +225,12 @@ namespace triagens {
static TRI_shape_t const* FailureFunction (TRI_shaper_t*, TRI_shape_t*, bool) {
TRI_ASSERT(false);
return 0;
}
static int64_t FailureFunction (TRI_shaper_t*, TRI_shape_aid_t) {
TRI_ASSERT(false);
return 0;
return nullptr;
}
static TRI_shape_path_t const* FailureFunction2 (TRI_shaper_t*, TRI_shape_pid_t) {
TRI_ASSERT(false);
return 0;
return nullptr;
}
static TRI_shape_pid_t FailureFunction2 (TRI_shaper_t*, char const*) {
@ -281,7 +276,6 @@ namespace triagens {
lookupAttributeId = lookupAttributeIdFunction;
findShape = FailureFunction;
lookupShapeId = lookupShapeIdFunction;
lookupAttributeWeight = FailureFunction;
lookupAttributePathByPid = FailureFunction2;
findOrCreateAttributePathByName = FailureFunction2;
lookupAttributePathByName = FailureFunction2;
@ -291,7 +285,7 @@ namespace triagens {
// nothing to do
}
char const* lookupAttributeIdMethod (TRI_shape_aid_t const aid) {
char const* lookupAttributeIdMethod (TRI_shape_aid_t const aid) const {
// binary search in AttributeIds
TRI_shape_size_t low = 0;
TRI_shape_size_t high = _numberAttributes;
@ -322,7 +316,7 @@ namespace triagens {
}
}
TRI_shape_t const* lookupShapeIdMethod (TRI_shape_sid_t const sid) {
TRI_shape_t const* lookupShapeIdMethod (TRI_shape_sid_t const sid) const {
// Is it a builtin basic one?
if (sid < TRI_FirstCustomShapeIdShaper()) {
return TRI_LookupSidBasicShapeShaper(sid);

View File

@ -43,58 +43,65 @@
// --SECTION-- GLOBALS
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief basic shape types (shared between all shapers)
////////////////////////////////////////////////////////////////////////////////
TRI_shape_pid_t const BasicShapes::TRI_SHAPE_SID_NULL = 1;
TRI_shape_pid_t const BasicShapes::TRI_SHAPE_SID_BOOLEAN = 2;
TRI_shape_pid_t const BasicShapes::TRI_SHAPE_SID_NUMBER = 3;
TRI_shape_pid_t const BasicShapes::TRI_SHAPE_SID_SHORT_STRING = 4;
TRI_shape_pid_t const BasicShapes::TRI_SHAPE_SID_LONG_STRING = 5;
TRI_shape_pid_t const BasicShapes::TRI_SHAPE_SID_LIST = 6;
TRI_shape_t const BasicShapes::_shapeNull = {
BasicShapes::TRI_SHAPE_SID_NULL,
TRI_SHAPE_NULL,
sizeof(TRI_null_shape_t),
0
};
static TRI_basic_shapes_t BasicShapes;
TRI_shape_t const BasicShapes::_shapeBoolean = {
BasicShapes::TRI_SHAPE_SID_BOOLEAN,
TRI_SHAPE_BOOLEAN,
sizeof(TRI_boolean_shape_t),
sizeof(TRI_shape_boolean_t)
};
// -----------------------------------------------------------------------------
// --SECTION-- ARRAY SHAPER
// -----------------------------------------------------------------------------
TRI_shape_t const BasicShapes::_shapeNumber = {
BasicShapes::TRI_SHAPE_SID_NUMBER,
TRI_SHAPE_NUMBER,
sizeof(TRI_number_shape_t),
sizeof(TRI_shape_number_t)
};
// -----------------------------------------------------------------------------
// --SECTION-- private types
// -----------------------------------------------------------------------------
TRI_shape_t const BasicShapes::_shapeShortString = {
BasicShapes::TRI_SHAPE_SID_SHORT_STRING,
TRI_SHAPE_SHORT_STRING,
sizeof(TRI_short_string_shape_t),
sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT
};
////////////////////////////////////////////////////////////////////////////////
/// @brief attribute identifier mapping
////////////////////////////////////////////////////////////////////////////////
TRI_shape_t const BasicShapes::_shapeLongString = {
BasicShapes::TRI_SHAPE_SID_LONG_STRING,
TRI_SHAPE_LONG_STRING,
sizeof(TRI_long_string_shape_t),
TRI_SHAPE_SIZE_VARIABLE
};
typedef struct attribute_2_id_s {
TRI_shape_aid_t _aid; // attribute identifier
TRI_shape_size_t _size; // size of the attribute name in name[] including '\0'
// char name[]
}
attribute_2_id_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief simple, array-based shaper
////////////////////////////////////////////////////////////////////////////////
typedef struct array_shaper_s {
TRI_shaper_t base;
TRI_associative_pointer_t _attributeNames;
TRI_vector_pointer_t _attributes;
TRI_associative_pointer_t _shapeDictionary;
TRI_vector_pointer_t _shapes;
// todo: add attribute weight structure
}
array_shaper_t;
TRI_shape_t const BasicShapes::_shapeList = {
BasicShapes::TRI_SHAPE_SID_LIST,
TRI_SHAPE_LIST,
sizeof(TRI_list_shape_t),
TRI_SHAPE_SIZE_VARIABLE
};
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief hashs the attribute path identifier
/// @brief hashes the attribute path identifier
////////////////////////////////////////////////////////////////////////////////
static uint64_t HashPidKeyAttributePath (TRI_associative_synced_t* array, void const* key) {
static uint64_t HashPidKeyAttributePath (TRI_associative_synced_t* array,
void const* key) {
return TRI_FnvHashPointer(key, sizeof(TRI_shape_pid_t));
}
@ -102,10 +109,9 @@ static uint64_t HashPidKeyAttributePath (TRI_associative_synced_t* array, void c
/// @brief hashs the attribute path
////////////////////////////////////////////////////////////////////////////////
static uint64_t HashPidElementAttributePath (TRI_associative_synced_t* array, void const* element) {
TRI_shape_path_t const* e;
e = (TRI_shape_path_t const*) element;
static uint64_t HashPidElementAttributePath (TRI_associative_synced_t* array,
void const* element) {
auto e = static_cast<TRI_shape_path_t const*>(element);
return TRI_FnvHashPointer(&e->_pid, sizeof(TRI_shape_pid_t));
}
@ -114,12 +120,11 @@ static uint64_t HashPidElementAttributePath (TRI_associative_synced_t* array, vo
/// @brief compares an attribute path identifier and an attribute path
////////////////////////////////////////////////////////////////////////////////
static bool EqualPidKeyAttributePath (TRI_associative_synced_t* array, void const* key, void const* element) {
TRI_shape_pid_t const* k;
TRI_shape_path_t const* e;
k = (TRI_shape_pid_t const*) key;
e = (TRI_shape_path_t const*) element;
static bool EqualPidKeyAttributePath (TRI_associative_synced_t* array,
void const* key,
void const* element) {
auto k = static_cast<TRI_shape_pid_t const*>(key);
auto e = static_cast<TRI_shape_path_t const*>(element);
return *k == e->_pid;
}
@ -128,7 +133,8 @@ static bool EqualPidKeyAttributePath (TRI_associative_synced_t* array, void cons
/// @brief looks up an attribute path by identifier
////////////////////////////////////////////////////////////////////////////////
static TRI_shape_path_t const* LookupAttributePathByPid (TRI_shaper_t* shaper, TRI_shape_pid_t pid) {
static TRI_shape_path_t const* LookupAttributePathByPid (TRI_shaper_t* shaper,
TRI_shape_pid_t pid) {
return static_cast<TRI_shape_path_t const*>(TRI_LookupByKeyAssociativeSynced(&shaper->_attributePathsByPid, &pid));
}
@ -136,24 +142,19 @@ static TRI_shape_path_t const* LookupAttributePathByPid (TRI_shaper_t* shaper, T
/// @brief hashs the attribute path name
////////////////////////////////////////////////////////////////////////////////
static uint64_t HashNameKeyAttributePath (TRI_associative_synced_t* array, void const* key) {
char const* k;
k = (char const*) key;
return TRI_FnvHashString(k);
static uint64_t HashNameKeyAttributePath (TRI_associative_synced_t* array,
void const* key) {
return TRI_FnvHashString(static_cast<char const*>(key));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief hashs the attribute path
////////////////////////////////////////////////////////////////////////////////
static uint64_t HashNameElementAttributePath (TRI_associative_synced_t* array, void const* element) {
char const* e;
TRI_shape_path_t const* ee;
e = (char const*) element;
ee = (TRI_shape_path_t const*) element;
static uint64_t HashNameElementAttributePath (TRI_associative_synced_t* array,
void const* element) {
char const* e = static_cast<char const*>(element);
TRI_shape_path_t const* ee = static_cast<TRI_shape_path_t const*>(element);
return TRI_FnvHashPointer(e + sizeof(TRI_shape_path_t) + ee->_aidLength * sizeof(TRI_shape_aid_t),
ee->_nameLength - 1);
@ -163,14 +164,12 @@ static uint64_t HashNameElementAttributePath (TRI_associative_synced_t* array, v
/// @brief compares an attribute name and an attribute
////////////////////////////////////////////////////////////////////////////////
static bool EqualNameKeyAttributePath (TRI_associative_synced_t* array, void const* key, void const* element) {
char const* k;
char const* e;
TRI_shape_path_t const* ee;
k = (char const*) key;
e = (char const*) element;
ee = (TRI_shape_path_t const*) element;
static bool EqualNameKeyAttributePath (TRI_associative_synced_t* array,
void const* key,
void const* element) {
char const* k = static_cast<char const*>(key);
char const* e = static_cast<char const*>(element);
TRI_shape_path_t const* ee = static_cast<TRI_shape_path_t const*>(element);
return TRI_EqualString(k,e + sizeof(TRI_shape_path_t) + ee->_aidLength * sizeof(TRI_shape_aid_t));
}
@ -182,27 +181,21 @@ static bool EqualNameKeyAttributePath (TRI_associative_synced_t* array, void con
static TRI_shape_path_t const* FindShapePathByName (TRI_shaper_t* shaper,
char const* name,
bool create) {
TRI_shape_aid_t* aids;
TRI_shape_path_t* result;
size_t count;
size_t len;
size_t total;
char* buffer;
char* end;
char* prev;
char* ptr;
void const* p;
TRI_ASSERT(name != nullptr);
p = TRI_LookupByKeyAssociativeSynced(&shaper->_attributePathsByName, name);
void const* p = TRI_LookupByKeyAssociativeSynced(&shaper->_attributePathsByName, name);
if (p != nullptr) {
return (TRI_shape_path_t const*) p;
}
// create a attribute path
len = strlen(name);
// create an attribute path
size_t len = strlen(name);
// lock the index and check that the element is still missing
TRI_LockMutex(&shaper->_attributePathLock);
@ -216,8 +209,8 @@ static TRI_shape_path_t const* FindShapePathByName (TRI_shaper_t* shaper,
}
// split path into attribute pieces
count = 0;
aids = static_cast<TRI_shape_aid_t*>(TRI_Allocate(shaper->_memoryZone, len * sizeof(TRI_shape_aid_t), false));
size_t count = 0;
TRI_shape_aid_t* aids = static_cast<TRI_shape_aid_t*>(TRI_Allocate(shaper->_memoryZone, len * sizeof(TRI_shape_aid_t), false));
if (aids == nullptr) {
TRI_UnlockMutex(&shaper->_attributePathLock);
@ -266,8 +259,8 @@ static TRI_shape_path_t const* FindShapePathByName (TRI_shaper_t* shaper,
TRI_FreeString(shaper->_memoryZone, buffer);
// create element
total = sizeof(TRI_shape_path_t) + (len + 1) + (count * sizeof(TRI_shape_aid_t));
result = static_cast<TRI_shape_path_t*>(TRI_Allocate(shaper->_memoryZone, total, false));
size_t total = sizeof(TRI_shape_path_t) + (len + 1) + (count * sizeof(TRI_shape_aid_t));
TRI_shape_path_t* result = static_cast<TRI_shape_path_t*>(TRI_Allocate(shaper->_memoryZone, total, false));
if (result == nullptr) {
TRI_UnlockMutex(&shaper->_attributePathLock);
@ -339,11 +332,8 @@ static TRI_shape_pid_t LookupAttributePathByName (TRI_shaper_t* shaper,
char const* TRI_AttributeNameShapePid (TRI_shaper_t* shaper,
TRI_shape_pid_t pid) {
TRI_shape_path_t const* path;
char const* e;
path = shaper->lookupAttributePathByPid(shaper, pid);
e = (char const*) path;
TRI_shape_path_t const* path = shaper->lookupAttributePathByPid(shaper, pid);
char const* e = (char const*) path;
return e + sizeof(TRI_shape_path_t) + path->_aidLength * sizeof(TRI_shape_aid_t);
}
@ -357,16 +347,14 @@ char const* TRI_AttributeNameShapePid (TRI_shaper_t* shaper,
////////////////////////////////////////////////////////////////////////////////
int TRI_InitShaper (TRI_shaper_t* shaper, TRI_memory_zone_t* zone) {
int res;
shaper->_memoryZone = zone;
res = TRI_InitAssociativeSynced(&shaper->_attributePathsByName,
zone,
HashNameKeyAttributePath,
HashNameElementAttributePath,
EqualNameKeyAttributePath,
0);
int res = TRI_InitAssociativeSynced(&shaper->_attributePathsByName,
zone,
HashNameKeyAttributePath,
HashNameElementAttributePath,
EqualNameKeyAttributePath,
0);
if (res != TRI_ERROR_NO_ERROR) {
return res;
@ -415,7 +403,6 @@ void TRI_DestroyShaper (TRI_shaper_t* shaper) {
TRI_DestroyAssociativeSynced(&shaper->_attributePathsByName);
TRI_DestroyAssociativeSynced(&shaper->_attributePathsByPid);
TRI_DestroyMutex(&shaper->_attributePathLock);
}
@ -428,60 +415,32 @@ void TRI_FreeShaper (TRI_shaper_t* shaper) {
TRI_Free(shaper->_memoryZone, shaper);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the sid for a basic type
////////////////////////////////////////////////////////////////////////////////
TRI_shape_sid_t TRI_LookupBasicSidShaper (TRI_shape_type_e type) {
switch (type) {
case TRI_SHAPE_NULL:
return BasicShapes._sidNull;
case TRI_SHAPE_BOOLEAN:
return BasicShapes._sidBoolean;
case TRI_SHAPE_NUMBER:
return BasicShapes._sidNumber;
case TRI_SHAPE_SHORT_STRING:
return BasicShapes._sidShortString;
case TRI_SHAPE_LONG_STRING:
return BasicShapes._sidLongString;
case TRI_SHAPE_LIST:
return BasicShapes._sidList;
default: {
}
}
LOG_ERROR("encountered an illegal shape type");
TRI_ASSERT(false);
return TRI_SHAPE_ILLEGAL;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks whether a shape is of primitive type
////////////////////////////////////////////////////////////////////////////////
TRI_shape_t* TRI_LookupSidBasicShapeShaper (TRI_shape_sid_t sid) {
TRI_shape_t const* TRI_LookupSidBasicShapeShaper (TRI_shape_sid_t sid) {
if (sid >= TRI_FirstCustomShapeIdShaper() || sid == 0) {
return nullptr;
}
if (sid == BasicShapes._sidNull) {
return &BasicShapes._shapeNull;
if (sid == BasicShapes::TRI_SHAPE_SID_NULL) {
return &BasicShapes::_shapeNull;
}
else if (sid == BasicShapes._sidBoolean) {
return &BasicShapes._shapeBoolean;
else if (sid == BasicShapes::TRI_SHAPE_SID_BOOLEAN) {
return &BasicShapes::_shapeBoolean;
}
else if (sid == BasicShapes._sidNumber) {
return &BasicShapes._shapeNumber;
else if (sid == BasicShapes::TRI_SHAPE_SID_NUMBER) {
return &BasicShapes::_shapeNumber;
}
else if (sid == BasicShapes._sidShortString) {
return &BasicShapes._shapeShortString;
else if (sid == BasicShapes::TRI_SHAPE_SID_SHORT_STRING) {
return &BasicShapes::_shapeShortString;
}
else if (sid == BasicShapes._sidLongString) {
return &BasicShapes._shapeLongString;
else if (sid == BasicShapes::TRI_SHAPE_SID_LONG_STRING) {
return &BasicShapes::_shapeLongString;
}
else if (sid == BasicShapes._sidList) {
return &BasicShapes._shapeList;
else if (sid == BasicShapes::TRI_SHAPE_SID_LIST) {
return &BasicShapes::_shapeList;
}
return nullptr;
@ -491,91 +450,29 @@ TRI_shape_t* TRI_LookupSidBasicShapeShaper (TRI_shape_sid_t sid) {
/// @brief checks whether a shape is of primitive type
////////////////////////////////////////////////////////////////////////////////
TRI_shape_t* TRI_LookupBasicShapeShaper (TRI_shape_t const* shape) {
TRI_shape_t const* TRI_LookupBasicShapeShaper (TRI_shape_t const* shape) {
if (shape->_type == TRI_SHAPE_NULL) {
return &BasicShapes._shapeNull;
return &BasicShapes::_shapeNull;
}
else if (shape->_type == TRI_SHAPE_BOOLEAN) {
return &BasicShapes._shapeBoolean;
return &BasicShapes::_shapeBoolean;
}
else if (shape->_type == TRI_SHAPE_NUMBER) {
return &BasicShapes._shapeNumber;
return &BasicShapes::_shapeNumber;
}
else if (shape->_type == TRI_SHAPE_SHORT_STRING) {
return &BasicShapes._shapeShortString;
return &BasicShapes::_shapeShortString;
}
else if (shape->_type == TRI_SHAPE_LONG_STRING) {
return &BasicShapes._shapeLongString;
return &BasicShapes::_shapeLongString;
}
else if (shape->_type == TRI_SHAPE_LIST) {
return &BasicShapes._shapeList;
return &BasicShapes::_shapeList;
}
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief initialises global basic shape types
////////////////////////////////////////////////////////////////////////////////
void TRI_InitialiseShaper () {
TRI_shape_t* shape;
memset(&BasicShapes, 0, sizeof(TRI_basic_shapes_t));
// NULL
shape = &BasicShapes._shapeNull;
shape->_size = sizeof(TRI_null_shape_t);
shape->_type = TRI_SHAPE_NULL;
shape->_dataSize = 0;
shape->_sid = BasicShapes._sidNull = 1;
// BOOLEAN
shape = &BasicShapes._shapeBoolean;
shape->_size = sizeof(TRI_boolean_shape_t);
shape->_type = TRI_SHAPE_BOOLEAN;
shape->_dataSize = sizeof(TRI_shape_boolean_t);
shape->_sid = BasicShapes._sidBoolean = 2;
// NUMBER
shape = &BasicShapes._shapeNumber;
shape->_size = sizeof(TRI_number_shape_t);
shape->_type = TRI_SHAPE_NUMBER;
shape->_dataSize = sizeof(TRI_shape_number_t);
shape->_sid = BasicShapes._sidNumber = 3;
// SHORT STRING
shape = &BasicShapes._shapeShortString;
shape->_size = sizeof(TRI_short_string_shape_t);
shape->_type = TRI_SHAPE_SHORT_STRING;
shape->_dataSize = sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT;
shape->_sid = BasicShapes._sidShortString = 4;
// LONG STRING
shape = &BasicShapes._shapeLongString;
shape->_size = sizeof(TRI_long_string_shape_t);
shape->_type = TRI_SHAPE_LONG_STRING;
shape->_dataSize = TRI_SHAPE_SIZE_VARIABLE;
shape->_sid = BasicShapes._sidLongString = 5;
// LIST
shape = &BasicShapes._shapeList;
shape->_size = sizeof(TRI_list_shape_t);
shape->_type = TRI_SHAPE_LIST;
shape->_dataSize = TRI_SHAPE_SIZE_VARIABLE;
shape->_sid = BasicShapes._sidList = 6;
TRI_ASSERT(shape->_sid + 1 == TRI_FirstCustomShapeIdShaper());
}
////////////////////////////////////////////////////////////////////////////////
/// @brief shutdown shaper
////////////////////////////////////////////////////////////////////////////////
void TRI_ShutdownShaper () {
// nothing to do
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

View File

@ -45,56 +45,39 @@
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief name of TRI_shape_path_t
/// @brief static const information about basic shape types
////////////////////////////////////////////////////////////////////////////////
#define TRI_NAME_SHAPE_PATH(path) \
(((char const*) path) + sizeof(TRI_shape_path_t) + path->_aidLength * sizeof(TRI_shape_aid_t))
struct BasicShapes {
static TRI_shape_pid_t const TRI_SHAPE_SID_NULL;
static TRI_shape_pid_t const TRI_SHAPE_SID_BOOLEAN;
static TRI_shape_pid_t const TRI_SHAPE_SID_NUMBER;
static TRI_shape_pid_t const TRI_SHAPE_SID_SHORT_STRING;
static TRI_shape_pid_t const TRI_SHAPE_SID_LONG_STRING;
static TRI_shape_pid_t const TRI_SHAPE_SID_LIST;
static TRI_shape_t const _shapeNull;
static TRI_shape_t const _shapeBoolean;
static TRI_shape_t const _shapeNumber;
static TRI_shape_t const _shapeShortString;
static TRI_shape_t const _shapeLongString;
static TRI_shape_t const _shapeList;
};
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief a const which represents an undefined weight
///
/// 2^63-1 to indicate that the attribute is weighted to be the lowest possible
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_UNDEFINED_ATTRIBUTE_WEIGHT (-9223372036854775807L)
////////////////////////////////////////////////////////////////////////////////
/// @brief global shape ids and pointers
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_basic_shapes_s {
TRI_shape_sid_t _sidNull;
TRI_shape_sid_t _sidBoolean;
TRI_shape_sid_t _sidNumber;
TRI_shape_sid_t _sidShortString;
TRI_shape_sid_t _sidLongString;
TRI_shape_sid_t _sidList;
TRI_shape_t _shapeNull;
TRI_shape_t _shapeBoolean;
TRI_shape_t _shapeNumber;
TRI_shape_t _shapeShortString;
TRI_shape_t _shapeLongString;
TRI_shape_t _shapeList;
}
TRI_basic_shapes_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json shaper
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_shaper_s {
TRI_shape_aid_t (*findOrCreateAttributeByName) (struct TRI_shaper_s*, char const*);
TRI_shape_aid_t (*findOrCreateAttributeByName) (struct TRI_shaper_s*, char const*);
TRI_shape_aid_t (*lookupAttributeByName) (struct TRI_shaper_s*, char const*);
char const* (*lookupAttributeId) (struct TRI_shaper_s*, TRI_shape_aid_t);
TRI_shape_t const* (*findShape) (struct TRI_shaper_s*, TRI_shape_t*, bool);
TRI_shape_t const* (*lookupShapeId) (struct TRI_shaper_s*, TRI_shape_sid_t);
int64_t (*lookupAttributeWeight) (struct TRI_shaper_s*, TRI_shape_aid_t);
TRI_shape_path_t const* (*lookupAttributePathByPid) (struct TRI_shaper_s*, TRI_shape_pid_t);
TRI_shape_pid_t (*findOrCreateAttributePathByName) (struct TRI_shaper_s*, char const*);
TRI_shape_pid_t (*lookupAttributePathByName) (struct TRI_shaper_s*, char const*);
@ -146,43 +129,25 @@ void TRI_DestroyShaper (TRI_shaper_t* shaper);
void TRI_FreeShaper (TRI_shaper_t* shaper);
////////////////////////////////////////////////////////////////////////////////
/// @brief return the sid for a basic type
/// @brief checks whether a shape is of primitive type
////////////////////////////////////////////////////////////////////////////////
TRI_shape_sid_t TRI_LookupBasicSidShaper (TRI_shape_type_e);
TRI_shape_t const* TRI_LookupSidBasicShapeShaper (TRI_shape_sid_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks whether a shape is of primitive type
////////////////////////////////////////////////////////////////////////////////
TRI_shape_t* TRI_LookupSidBasicShapeShaper (TRI_shape_sid_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks whether a shape is of primitive type
////////////////////////////////////////////////////////////////////////////////
TRI_shape_t* TRI_LookupBasicShapeShaper (TRI_shape_t const*);
TRI_shape_t const* TRI_LookupBasicShapeShaper (TRI_shape_t const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the first id for user-defined shapes
////////////////////////////////////////////////////////////////////////////////
static inline TRI_shape_sid_t TRI_FirstCustomShapeIdShaper (void) {
return 7;
return BasicShapes::TRI_SHAPE_SID_LIST + 1;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief initialises global basic shape types
////////////////////////////////////////////////////////////////////////////////
void TRI_InitialiseShaper (void);
////////////////////////////////////////////////////////////////////////////////
/// @brief shutdown shaper
////////////////////////////////////////////////////////////////////////////////
void TRI_ShutdownShaper (void);
#endif
// -----------------------------------------------------------------------------

View File

@ -36,6 +36,21 @@
// #define DEBUG_SHAPE_ACCESSOR 1
// -----------------------------------------------------------------------------
// --SECTION-- private types
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief shape accessor bytecode operations
////////////////////////////////////////////////////////////////////////////////
typedef enum {
TRI_SHAPE_AC_DONE = 1,
TRI_SHAPE_AC_OFFSET_FIX = 2,
TRI_SHAPE_AC_OFFSET_VAR = 3
}
TRI_shape_ac_bc_e;
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
@ -44,17 +59,10 @@
/// @brief computes a byte-code sequence
////////////////////////////////////////////////////////////////////////////////
static bool BytecodeShapeAccessor (TRI_shaper_t* shaper, TRI_shape_access_t* accessor) {
TRI_shape_aid_t const* paids;
TRI_shape_path_t const* path;
TRI_shape_t const* shape;
TRI_vector_pointer_t ops;
size_t i;
size_t j;
int res;
static bool BytecodeShapeAccessor (TRI_shaper_t* shaper,
TRI_shape_access_t* accessor) {
// find the shape
shape = shaper->lookupShapeId(shaper, accessor->_sid);
TRI_shape_t const* shape = shaper->lookupShapeId(shaper, accessor->_sid);
if (shape == nullptr) {
LOG_ERROR("unknown shape id %llu", (unsigned long long) accessor->_sid);
@ -65,7 +73,7 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper, TRI_shape_access_t* acc
}
// find the attribute path
path = shaper->lookupAttributePathByPid(shaper, accessor->_pid);
TRI_shape_path_t const* path = shaper->lookupAttributePathByPid(shaper, accessor->_pid);
if (path == nullptr) {
LOG_ERROR("unknown attribute path %llu", (unsigned long long) accessor->_pid);
@ -75,15 +83,16 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper, TRI_shape_access_t* acc
return false;
}
paids = (TRI_shape_aid_t*) (((char const*) path) + sizeof(TRI_shape_path_t));
TRI_shape_aid_t const* paids = (TRI_shape_aid_t*) (((char const*) path) + sizeof(TRI_shape_path_t));
// collect the bytecode
// we need at least 2 entries in the vector to store an accessor
TRI_InitVectorPointer2(&ops, shaper->_memoryZone, 2);
// we need at least 3 or 4 entries in the vector to store an accessor
TRI_vector_pointer_t ops;
TRI_InitVectorPointer2(&ops, TRI_UNKNOWN_MEM_ZONE, 4);
// and follow it
for (i = 0; i < path->_aidLength; ++i, ++paids) {
for (size_t i = 0; i < path->_aidLength; ++i, ++paids) {
#ifdef DEBUG_SHAPE_ACCESSOR
printf("%lu: aid: %lu, sid: %lu, type %lu\n",
(unsigned long) i,
@ -120,6 +129,8 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper, TRI_shape_access_t* acc
offsetsF = (TRI_shape_size_t const*) qtr;
size_t j;
// check for fixed size aid
for (j = 0; j < f; ++j, ++sids, ++aids, ++offsetsF) {
if (*paids == *aids) {
@ -142,7 +153,7 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper, TRI_shape_access_t* acc
return false;
}
res = TRI_PushBackVectorPointer(&ops, (void*) TRI_SHAPE_AC_OFFSET_FIX);
int res = TRI_PushBackVectorPointer(&ops, (void*) TRI_SHAPE_AC_OFFSET_FIX);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("out of memory");
@ -195,7 +206,7 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper, TRI_shape_access_t* acc
return false;
}
res = TRI_PushBackVectorPointer(&ops, (void*) TRI_SHAPE_AC_OFFSET_VAR);
int res = TRI_PushBackVectorPointer(&ops, (void*) TRI_SHAPE_AC_OFFSET_VAR);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("out of memory");
@ -231,7 +242,7 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper, TRI_shape_access_t* acc
}
// travel attribute path to the end
res = TRI_PushBackVectorPointer(&ops, (void*) TRI_SHAPE_AC_DONE);
int res = TRI_PushBackVectorPointer(&ops, (void*) TRI_SHAPE_AC_DONE);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("out of memory");
@ -259,11 +270,6 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper, TRI_shape_access_t* acc
static bool ExecuteBytecodeShapeAccessor (TRI_shape_access_t const* accessor,
void** begin,
void** end) {
TRI_shape_size_t b;
TRI_shape_size_t e;
TRI_shape_size_t pos;
TRI_shape_size_t* offsetsV;
if (accessor->_resultSid == TRI_SHAPE_ILLEGAL) {
return false;
}
@ -278,27 +284,26 @@ static bool ExecuteBytecodeShapeAccessor (TRI_shape_access_t const* accessor,
case TRI_SHAPE_AC_DONE:
return true;
case TRI_SHAPE_AC_OFFSET_FIX:
b = (TRI_shape_size_t) (uintptr_t) *ops++; // offset is always smaller than 4 GByte
e = (TRI_shape_size_t) (uintptr_t) *ops++; // offset is always smaller than 4 GByte
case TRI_SHAPE_AC_OFFSET_FIX: {
TRI_shape_size_t b = (TRI_shape_size_t) (uintptr_t) *ops++; // offset is always smaller than 4 GByte
TRI_shape_size_t e = (TRI_shape_size_t) (uintptr_t) *ops++; // offset is always smaller than 4 GByte
*end = ((char*) *begin) + e;
*begin = ((char*) *begin) + b;
break;
}
case TRI_SHAPE_AC_OFFSET_VAR:
pos = (TRI_shape_size_t) (uintptr_t) *ops++; // offset is always smaller than 4 GByte
offsetsV = (TRI_shape_size_t*) *begin;
case TRI_SHAPE_AC_OFFSET_VAR: {
TRI_shape_size_t pos = (TRI_shape_size_t) (uintptr_t) *ops++; // offset is always smaller than 4 GByte
TRI_shape_size_t* offsetsV = (TRI_shape_size_t*) *begin;
*end = ((char*) *begin) + offsetsV[pos + 1];
*begin = ((char*) *begin) + offsetsV[pos];
break;
}
default:
return false;
break;
}
}
@ -317,10 +322,10 @@ void TRI_FreeShapeAccessor (TRI_shape_access_t* accessor) {
TRI_ASSERT(accessor != nullptr);
if (accessor->_code != nullptr) {
TRI_Free(accessor->_memoryZone, (void*) accessor->_code);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, (void*) accessor->_code);
}
TRI_Free(accessor->_memoryZone, accessor);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, accessor);
}
////////////////////////////////////////////////////////////////////////////////
@ -330,7 +335,7 @@ void TRI_FreeShapeAccessor (TRI_shape_access_t* accessor) {
TRI_shape_access_t* TRI_ShapeAccessor (TRI_shaper_t* shaper,
TRI_shape_sid_t sid,
TRI_shape_pid_t pid) {
TRI_shape_access_t* accessor = static_cast<TRI_shape_access_t*>(TRI_Allocate(shaper->_memoryZone, sizeof(TRI_shape_access_t), false));
TRI_shape_access_t* accessor = static_cast<TRI_shape_access_t*>(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shape_access_t), false));
if (accessor == nullptr) {
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
@ -340,7 +345,6 @@ TRI_shape_access_t* TRI_ShapeAccessor (TRI_shaper_t* shaper,
accessor->_sid = sid;
accessor->_pid = pid;
accessor->_code = nullptr;
accessor->_memoryZone = shaper->_memoryZone;
bool ok = BytecodeShapeAccessor(shaper, accessor);

View File

@ -49,22 +49,9 @@ typedef struct TRI_shape_access_s {
TRI_shape_sid_t _resultSid; // resulting shape
void const** _code; // bytecode
TRI_memory_zone_t* _memoryZone;
}
TRI_shape_access_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief shape accessor bytecode operations
////////////////////////////////////////////////////////////////////////////////
typedef enum {
TRI_SHAPE_AC_DONE = 1,
TRI_SHAPE_AC_OFFSET_FIX = 2,
TRI_SHAPE_AC_OFFSET_VAR = 3
}
TRI_shape_ac_bc_e;
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------

View File

@ -209,11 +209,8 @@ void TRI_PrintShape (TRI_shaper_t* shaper, TRI_shape_t const* shape, int indent)
static void PrintShapeValues (TRI_shape_value_t* values,
size_t n) {
TRI_shape_value_t* p;
TRI_shape_value_t* e;
p = values;
e = values + n;
TRI_shape_value_t* p = values;
TRI_shape_value_t* e = values + n;
for (; p < e; ++p) {
switch (p->_type) {
@ -310,7 +307,6 @@ static void PrintShapeValues (TRI_shape_value_t* values,
static int WeightShapeType (TRI_shape_type_t type) {
switch (type) {
case TRI_SHAPE_NULL: return 100;
case TRI_SHAPE_BOOLEAN: return 200;
case TRI_SHAPE_NUMBER: return 300;
@ -335,20 +331,15 @@ static int WeightShapeType (TRI_shape_type_t type) {
////////////////////////////////////////////////////////////////////////////////
static int SortShapeValuesFunc (void const* l, void const* r) {
TRI_shape_value_t const* left;
TRI_shape_value_t const* right;
int wl;
int wr;
left = (TRI_shape_value_t const*) l;
right = (TRI_shape_value_t const*) r;
auto left = static_cast<TRI_shape_value_t const*>(l);
auto right = static_cast<TRI_shape_value_t const*>(r);
if (left->_fixedSized != right->_fixedSized) {
return (left->_fixedSized ? 0 : 1) - (right->_fixedSized ? 0 : 1);
}
wl = WeightShapeType(left->_type);
wr = WeightShapeType(right->_type);
int wl = WeightShapeType(left->_type);
int wr = WeightShapeType(right->_type);
if (wl != wr) {
return wl - wr;
@ -363,7 +354,7 @@ static int SortShapeValuesFunc (void const* l, void const* r) {
static bool FillShapeValueNull (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TRI_json_t const* json) {
dst->_type = TRI_SHAPE_NULL;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_NULL);
dst->_sid = BasicShapes::TRI_SHAPE_SID_NULL;
dst->_fixedSized = true;
dst->_size = 0;
dst->_value = 0;
@ -379,7 +370,7 @@ static bool FillShapeValueBoolean (TRI_shaper_t* shaper, TRI_shape_value_t* dst,
TRI_shape_boolean_t* ptr;
dst->_type = TRI_SHAPE_BOOLEAN;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_BOOLEAN);
dst->_sid = BasicShapes::TRI_SHAPE_SID_BOOLEAN;
dst->_fixedSized = true;
dst->_size = sizeof(TRI_shape_boolean_t);
// no need to prefill dst->_value with 0, as it is overwritten directly afterwards
@ -402,7 +393,7 @@ static bool FillShapeValueNumber (TRI_shaper_t* shaper, TRI_shape_value_t* dst,
TRI_shape_number_t* ptr;
dst->_type = TRI_SHAPE_NUMBER;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_NUMBER);
dst->_sid = BasicShapes::TRI_SHAPE_SID_NUMBER;
dst->_fixedSized = true;
dst->_size = sizeof(TRI_shape_number_t);
dst->_value = (char*) (ptr = static_cast<TRI_shape_number_t*>(TRI_Allocate(shaper->_memoryZone, dst->_size, false)));
@ -425,7 +416,7 @@ static bool FillShapeValueString (TRI_shaper_t* shaper, TRI_shape_value_t* dst,
if (json->_value._string.length <= TRI_SHAPE_SHORT_STRING_CUT) { // includes '\0'
dst->_type = TRI_SHAPE_SHORT_STRING;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_SHORT_STRING);
dst->_sid = BasicShapes::TRI_SHAPE_SID_SHORT_STRING;
dst->_fixedSized = true;
dst->_size = sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT;
// must fill with 0's because the string might be shorter, and we might use the
@ -444,7 +435,7 @@ static bool FillShapeValueString (TRI_shaper_t* shaper, TRI_shape_value_t* dst,
}
else {
dst->_type = TRI_SHAPE_LONG_STRING;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_LONG_STRING);
dst->_sid = BasicShapes::TRI_SHAPE_SID_LONG_STRING;
dst->_fixedSized = false;
dst->_size = sizeof(TRI_shape_length_long_string_t) + json->_value._string.length;
dst->_value = (ptr = static_cast<char*>(TRI_Allocate(shaper->_memoryZone, dst->_size, false)));
@ -500,8 +491,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
if (n == 0) {
dst->_type = TRI_SHAPE_LIST;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_LIST);
dst->_sid = BasicShapes::TRI_SHAPE_SID_LIST;
dst->_fixedSized = false;
dst->_size = sizeof(TRI_shape_length_list_t);
dst->_value = (ptr = static_cast<char*>(TRI_Allocate(shaper->_memoryZone, dst->_size, false)));
@ -713,7 +703,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
// in-homogeneous
else {
dst->_type = TRI_SHAPE_LIST;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_LIST);
dst->_sid = BasicShapes::TRI_SHAPE_SID_LIST;
offset =
sizeof(TRI_shape_length_list_t)
@ -1074,9 +1064,7 @@ static TRI_json_t* JsonShapeDataBoolean (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
bool v;
v = (* (TRI_shape_boolean_t const*) data) != 0;
bool v = (* (TRI_shape_boolean_t const*) data) != 0;
return TRI_CreateBooleanJson(shaper->_memoryZone, v);
}
@ -1089,9 +1077,7 @@ static TRI_json_t* JsonShapeDataNumber (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
TRI_shape_number_t v;
v = * (TRI_shape_number_t const*) (void const*) data;
TRI_shape_number_t v = * (TRI_shape_number_t const*) (void const*) data;
return TRI_CreateNumberJson(shaper->_memoryZone, v);
}
@ -1104,9 +1090,7 @@ static TRI_json_t* JsonShapeDataShortString (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
TRI_shape_length_short_string_t l;
l = * (TRI_shape_length_short_string_t const*) data;
TRI_shape_length_short_string_t l = * (TRI_shape_length_short_string_t const*) data;
data += sizeof(TRI_shape_length_short_string_t);
return TRI_CreateStringCopyJson(shaper->_memoryZone, data, (size_t) (l - 1));
@ -1120,9 +1104,7 @@ static TRI_json_t* JsonShapeDataLongString (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
TRI_shape_length_long_string_t l;
l = * (TRI_shape_length_long_string_t const*) data;
TRI_shape_length_long_string_t l = * (TRI_shape_length_long_string_t const*) data;
data += sizeof(TRI_shape_length_long_string_t);
return TRI_CreateStringCopyJson(shaper->_memoryZone, data, l - 1);
@ -1524,9 +1506,7 @@ static bool StringifyJsonShapeDataNull (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
int res;
res = TRI_AppendString2StringBuffer(buffer, "null", 4);
int res = TRI_AppendString2StringBuffer(buffer, "null", 4);
if (res != TRI_ERROR_NO_ERROR) {
return false;
@ -1544,10 +1524,9 @@ static bool StringifyJsonShapeDataBoolean (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
bool v;
int res;
v = (* (TRI_shape_boolean_t const*) data) != 0;
bool v = (* (TRI_shape_boolean_t const*) data) != 0;
if (v) {
res = TRI_AppendString2StringBuffer(buffer, "true", 4);
@ -1572,10 +1551,9 @@ static bool StringifyJsonShapeDataNumber (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
TRI_shape_number_t v;
int res;
v = * (TRI_shape_number_t const*) (void const*) data;
TRI_shape_number_t v = * (TRI_shape_number_t const*) (void const*) data;
// check for special values
// yes, this is intentional
@ -1611,11 +1589,9 @@ static bool StringifyJsonShapeDataShortString (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
int res;
data += sizeof(TRI_shape_length_short_string_t);
res = TRI_AppendCharStringBuffer(buffer, '"');
int res = TRI_AppendCharStringBuffer(buffer, '"');
if (res != TRI_ERROR_NO_ERROR) {
return false;
@ -1645,11 +1621,9 @@ static bool StringifyJsonShapeDataLongString (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
int res;
data += sizeof(TRI_shape_length_long_string_t);
res = TRI_AppendCharStringBuffer(buffer, '"');
int res = TRI_AppendCharStringBuffer(buffer, '"');
if (res != TRI_ERROR_NO_ERROR) {
return false;
@ -2238,7 +2212,7 @@ TRI_shaped_json_t* TRI_ShapedJsonJson (TRI_shaper_t* shaper,
bool create) {
TRI_shape_value_t dst;
dst._value = 0;
dst._value = nullptr;
bool ok = FillShapeValueJson(shaper, &dst, json, 0, create);
if (! ok) {
@ -2255,7 +2229,9 @@ TRI_shaped_json_t* TRI_ShapedJsonJson (TRI_shaper_t* shaper,
TRI_shaped_json_t* shaped = static_cast<TRI_shaped_json_t*>(TRI_Allocate(shaper->_memoryZone, sizeof(TRI_shaped_json_t), false));
if (shaped == nullptr) {
TRI_Free(shaper->_memoryZone, dst._value);
if (dst._value != nullptr) {
TRI_Free(shaper->_memoryZone, dst._value);
}
return nullptr;
}
@ -2272,9 +2248,7 @@ TRI_shaped_json_t* TRI_ShapedJsonJson (TRI_shaper_t* shaper,
TRI_json_t* TRI_JsonShapedJson (TRI_shaper_t* shaper,
TRI_shaped_json_t const* shaped) {
TRI_shape_t const* shape;
shape = shaper->lookupShapeId(shaper, shaped->_sid);
TRI_shape_t const* shape = shaper->lookupShapeId(shaper, shaped->_sid);
if (shape == nullptr) {
LOG_WARNING("cannot find shape #%u", (unsigned int) shaped->_sid);
@ -2300,9 +2274,7 @@ bool TRI_StringifyArrayShapedJson (TRI_shaper_t* shaper,
}
if (prepend) {
TRI_array_shape_t const* s;
s = (TRI_array_shape_t const*) shape;
TRI_array_shape_t const* s = (TRI_array_shape_t const*) shape;
if (s->_fixedEntries + s->_variableEntries > 0) {
TRI_AppendCharStringBuffer(buffer, ',');
}
@ -2337,12 +2309,7 @@ bool TRI_StringifyAugmentedShapedJson (TRI_shaper_t* shaper,
struct TRI_string_buffer_s* buffer,
TRI_shaped_json_t const* shaped,
TRI_json_t const* augment) {
TRI_shape_t const* shape;
bool ok;
uint64_t num;
int res;
shape = shaper->lookupShapeId(shaper, shaped->_sid);
TRI_shape_t const* shape = shaper->lookupShapeId(shaper, shaped->_sid);
if (shape == nullptr) {
return false;
@ -2352,13 +2319,14 @@ bool TRI_StringifyAugmentedShapedJson (TRI_shaper_t* shaper,
return StringifyJsonShapeData(shaper, buffer, shape, shaped->_data.data, shaped->_data.length);
}
res = TRI_AppendCharStringBuffer(buffer, '{');
int res = TRI_AppendCharStringBuffer(buffer, '{');
if (res != TRI_ERROR_NO_ERROR) {
return false;
}
ok = StringifyJsonShapeDataArray(shaper, buffer, shape, shaped->_data.data, shaped->_data.length, false, &num);
uint64_t num;
bool ok = StringifyJsonShapeDataArray(shaper, buffer, shape, shaped->_data.data, shaped->_data.length, false, &num);
if (0 < num) {
res = TRI_AppendCharStringBuffer(buffer, ',');
@ -2404,19 +2372,14 @@ bool TRI_AtListShapedJson (TRI_list_shape_t const* shape,
TRI_shaped_json_t const* json,
size_t position,
TRI_shaped_json_t* result) {
TRI_shape_length_list_t n;
TRI_shape_sid_t* sids;
TRI_shape_size_t* offsets;
char const* ptr;
ptr = json->_data.data;
n = * (TRI_shape_length_list_t*) ptr;
char const* ptr = json->_data.data;
TRI_shape_length_list_t n = * (TRI_shape_length_list_t*) ptr;
ptr += sizeof(TRI_shape_length_list_t);
sids = (TRI_shape_sid_t*) ptr;
TRI_shape_sid_t* sids = (TRI_shape_sid_t*) ptr;
ptr += n * sizeof(TRI_shape_sid_t);
offsets = (TRI_shape_size_t*) ptr;
TRI_shape_size_t* offsets = (TRI_shape_size_t*) ptr;
result->_sid = sids[position];
result->_data.data = ((char*) json->_data.data) + offsets[position];
@ -2442,19 +2405,15 @@ bool TRI_AtHomogeneousListShapedJson (TRI_homogeneous_list_shape_t const* shape,
TRI_shaped_json_t const* json,
size_t position,
TRI_shaped_json_t* result) {
TRI_shape_length_list_t n;
TRI_shape_size_t* offsets;
char const* ptr;
ptr = json->_data.data;
n = * (TRI_shape_length_list_t*) ptr;
char const* ptr = json->_data.data;
TRI_shape_length_list_t n = * (TRI_shape_length_list_t*) ptr;
if (n <= position) {
return false;
}
ptr += sizeof(TRI_shape_length_list_t);
offsets = (TRI_shape_size_t*) ptr;
TRI_shape_size_t* offsets = (TRI_shape_size_t*) ptr;
result->_sid = shape->_sidEntry;
result->_data.data = ((char*) json->_data.data) + offsets[position];
@ -2480,11 +2439,8 @@ bool TRI_AtHomogeneousSizedListShapedJson (TRI_homogeneous_sized_list_shape_t co
TRI_shaped_json_t const* json,
size_t position,
TRI_shaped_json_t* result) {
TRI_shape_length_list_t n;
char* ptr;
ptr = json->_data.data;
n = * (TRI_shape_length_list_t*) ptr;
char* ptr = json->_data.data;
TRI_shape_length_list_t n = * (TRI_shape_length_list_t*) ptr;
if (n <= position) {
return false;
@ -2505,8 +2461,8 @@ bool TRI_AtHomogeneousSizedListShapedJson (TRI_homogeneous_sized_list_shape_t co
/// variables passed by reference
////////////////////////////////////////////////////////////////////////////////
bool TRI_StringValueShapedJson (const TRI_shape_t* const shape,
const char* data,
bool TRI_StringValueShapedJson (TRI_shape_t const* shape,
char const* data,
char** value,
size_t* length) {
if (shape->_type == TRI_SHAPE_SHORT_STRING) {

View File

@ -869,8 +869,15 @@ TRI_shaped_json_t;
typedef struct TRI_shaped_sub_s {
TRI_shape_sid_t _sid;
uint32_t _offset;
uint32_t _length;
union {
char _data[8];
struct {
uint32_t _offset;
uint32_t _length;
}
_position;
}
_value;
}
TRI_shaped_sub_t;
@ -1043,8 +1050,8 @@ void TRI_PrintShape (struct TRI_shaper_s* shaper,
/// variables passed by reference
////////////////////////////////////////////////////////////////////////////////
bool TRI_StringValueShapedJson (const TRI_shape_t* const,
const char*,
bool TRI_StringValueShapedJson (TRI_shape_t const*,
char const*,
char**,
size_t*);

View File

@ -97,9 +97,9 @@ shape_cache_t;
////////////////////////////////////////////////////////////////////////////////
static int FillShapeValueNull (TRI_shaper_t* shaper,
TRI_shape_value_t* dst) {
TRI_shape_value_t* dst) {
dst->_type = TRI_SHAPE_NULL;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_NULL);
dst->_sid = BasicShapes::TRI_SHAPE_SID_NULL;
dst->_fixedSized = true;
dst->_size = 0;
dst->_value = nullptr;
@ -117,7 +117,7 @@ static int FillShapeValueBoolean (TRI_shaper_t* shaper,
TRI_shape_boolean_t* ptr;
dst->_type = TRI_SHAPE_BOOLEAN;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_BOOLEAN);
dst->_sid = BasicShapes::TRI_SHAPE_SID_BOOLEAN;
dst->_fixedSized = true;
dst->_size = sizeof(TRI_shape_boolean_t);
dst->_value = (char*) (ptr = (TRI_shape_boolean_t*) TRI_Allocate(shaper->_memoryZone, dst->_size, false));
@ -141,7 +141,7 @@ static int FillShapeValueBoolean (TRI_shaper_t* shaper,
TRI_shape_boolean_t* ptr;
dst->_type = TRI_SHAPE_BOOLEAN;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_BOOLEAN);
dst->_sid = BasicShapes::TRI_SHAPE_SID_BOOLEAN;
dst->_fixedSized = true;
dst->_size = sizeof(TRI_shape_boolean_t);
dst->_value = (char*) (ptr = (TRI_shape_boolean_t*) TRI_Allocate(shaper->_memoryZone, dst->_size, false));
@ -165,7 +165,7 @@ static int FillShapeValueNumber (TRI_shaper_t* shaper,
TRI_shape_number_t* ptr;
dst->_type = TRI_SHAPE_NUMBER;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_NUMBER);
dst->_sid = BasicShapes::TRI_SHAPE_SID_NUMBER;
dst->_fixedSized = true;
dst->_size = sizeof(TRI_shape_number_t);
dst->_value = (char*) (ptr = (TRI_shape_number_t*) TRI_Allocate(shaper->_memoryZone, dst->_size, false));
@ -189,7 +189,7 @@ static int FillShapeValueNumber (TRI_shaper_t* shaper,
TRI_shape_number_t* ptr;
dst->_type = TRI_SHAPE_NUMBER;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_NUMBER);
dst->_sid = BasicShapes::TRI_SHAPE_SID_NUMBER;
dst->_fixedSized = true;
dst->_size = sizeof(TRI_shape_number_t);
dst->_value = (char*) (ptr = (TRI_shape_number_t*) TRI_Allocate(shaper->_memoryZone, dst->_size, false));
@ -214,10 +214,10 @@ static int FillShapeValueString (TRI_shaper_t* shaper,
TRI_Utf8ValueNFC str(TRI_UNKNOWN_MEM_ZONE, json);
if (*str == 0) {
if (*str == nullptr) {
// empty string
dst->_type = TRI_SHAPE_SHORT_STRING;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_SHORT_STRING);
dst->_sid = BasicShapes::TRI_SHAPE_SID_SHORT_STRING;
dst->_fixedSized = true;
dst->_size = sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT;
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, true));
@ -233,7 +233,7 @@ static int FillShapeValueString (TRI_shaper_t* shaper,
if (size < TRI_SHAPE_SHORT_STRING_CUT) { // includes '\0'
dst->_type = TRI_SHAPE_SHORT_STRING;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_SHORT_STRING);
dst->_sid = BasicShapes::TRI_SHAPE_SID_SHORT_STRING;
dst->_fixedSized = true;
dst->_size = sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT;
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, true));
@ -247,7 +247,7 @@ static int FillShapeValueString (TRI_shaper_t* shaper,
}
else {
dst->_type = TRI_SHAPE_LONG_STRING;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_LONG_STRING);
dst->_sid = BasicShapes::TRI_SHAPE_SID_LONG_STRING;
dst->_fixedSized = false;
dst->_size = sizeof(TRI_shape_length_long_string_t) + size + 1;
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, false));
@ -300,8 +300,7 @@ static int FillShapeValueList (v8::Isolate* isolate,
if (n == 0) {
dst->_type = TRI_SHAPE_LIST;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_LIST);
dst->_sid = BasicShapes::TRI_SHAPE_SID_LIST;
dst->_fixedSized = false;
dst->_size = sizeof(TRI_shape_length_list_t);
dst->_value = (ptr = static_cast<char*>(TRI_Allocate(shaper->_memoryZone, dst->_size, false)));
@ -522,7 +521,7 @@ static int FillShapeValueList (v8::Isolate* isolate,
// in-homogeneous
else {
dst->_type = TRI_SHAPE_LIST;
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_LIST);
dst->_sid = BasicShapes::TRI_SHAPE_SID_LIST;
offset =
sizeof(TRI_shape_length_list_t)
@ -849,12 +848,45 @@ static int FillShapeValueJson (v8::Isolate* isolate,
vector<v8::Handle<v8::Object>>& seenObjects,
bool create) {
v8::HandleScope scope(isolate);
if (json->IsRegExp() || json->IsFunction() || json->IsExternal()) {
LOG_TRACE("shaper failed because regexp/function/external/date object cannot be converted");
return TRI_ERROR_BAD_PARAMETER;
}
if (json->IsObject() && ! json->IsArray()) {
if (json->IsNull() || json->IsUndefined()) {
return FillShapeValueNull(shaper, dst);
}
if (json->IsBoolean()) {
return FillShapeValueBoolean(shaper, dst, json->ToBoolean());
}
if (json->IsBooleanObject()) {
return FillShapeValueBoolean(shaper, dst, v8::Handle<v8::BooleanObject>::Cast(json));
}
if (json->IsNumber()) {
return FillShapeValueNumber(shaper, dst, json->ToNumber());
}
if (json->IsNumberObject()) {
return FillShapeValueNumber(shaper, dst, v8::Handle<v8::NumberObject>::Cast(json));
}
if (json->IsString()) {
return FillShapeValueString(shaper, dst, json->ToString());
}
if (json->IsStringObject()) {
return FillShapeValueString(shaper, dst, v8::Handle<v8::StringObject>::Cast(json)->ValueOf());
}
else if (json->IsArray()) {
return FillShapeValueList(isolate, shaper, dst, v8::Handle<v8::Array>::Cast(json), level, seenHashes, seenObjects, create);
}
if (json->IsObject()) {
v8::Handle<v8::Object> o = json->ToObject();
v8::Handle<v8::String> toJsonString = TRI_V8_ASCII_STRING("toJSON");
if (o->Has(toJsonString)) {
@ -877,11 +909,8 @@ static int FillShapeValueJson (v8::Isolate* isolate,
int hash = o->GetIdentityHash();
if (seenHashes.find(hash) != seenHashes.end()) {
// LOG_TRACE("found hash %d", hash);
for (auto it = seenObjects.begin(); it != seenObjects.end(); ++it) {
if (json->StrictEquals(*it)) {
LOG_TRACE("found duplicate for hash %d", hash);
return TRI_ERROR_ARANGO_SHAPER_FAILED;
}
}
@ -891,41 +920,6 @@ static int FillShapeValueJson (v8::Isolate* isolate,
}
seenObjects.push_back(o);
}
if (json->IsNull() || json->IsUndefined()) {
return FillShapeValueNull(shaper, dst);
}
else if (json->IsBoolean()) {
return FillShapeValueBoolean(shaper, dst, json->ToBoolean());
}
else if (json->IsBooleanObject()) {
return FillShapeValueBoolean(shaper, dst, v8::Handle<v8::BooleanObject>::Cast(json));
}
else if (json->IsNumber()) {
return FillShapeValueNumber(shaper, dst, json->ToNumber());
}
else if (json->IsNumberObject()) {
return FillShapeValueNumber(shaper, dst, v8::Handle<v8::NumberObject>::Cast(json));
}
else if (json->IsString()) {
return FillShapeValueString(shaper, dst, json->ToString());
}
else if (json->IsStringObject()) {
return FillShapeValueString(shaper, dst, v8::Handle<v8::StringObject>::Cast(json)->ValueOf());
}
else if (json->IsArray()) {
return FillShapeValueList(isolate, shaper, dst, v8::Handle<v8::Array>::Cast(json), level, seenHashes, seenObjects, create);
}
else if (json->IsObject()) {
int res = FillShapeValueArray(isolate, shaper, dst, json->ToObject(), level, seenHashes, seenObjects, create);
seenObjects.pop_back();
// cannot remove hash value from seenHashes because multiple objects might have the same
@ -958,9 +952,7 @@ static v8::Handle<v8::Value> JsonShapeDataBoolean (v8::Isolate* isolate,
TRI_shape_t const* shape,
char const* data,
size_t size) {
bool v;
v = (* (TRI_shape_boolean_t const*) data) != 0;
bool v = (* (TRI_shape_boolean_t const*) data) != 0;
return v8::Boolean::New(isolate, v);
}
@ -974,9 +966,7 @@ static v8::Handle<v8::Value> JsonShapeDataNumber (v8::Isolate* isolate,
TRI_shape_t const* shape,
char const* data,
size_t size) {
TRI_shape_number_t v;
v = * (TRI_shape_number_t const*) data;
TRI_shape_number_t v = * (TRI_shape_number_t const*) data;
return v8::Number::New(isolate, v);
}
@ -990,9 +980,7 @@ static v8::Handle<v8::Value> JsonShapeDataShortString (v8::Isolate* isolate,
TRI_shape_t const* shape,
char const* data,
size_t size) {
TRI_shape_length_short_string_t l;
l = * (TRI_shape_length_short_string_t const*) data;
TRI_shape_length_short_string_t l = * (TRI_shape_length_short_string_t const*) data;
data += sizeof(TRI_shape_length_short_string_t);
return TRI_V8_PAIR_STRING(data, l - 1);
@ -1007,9 +995,7 @@ static v8::Handle<v8::Value> JsonShapeDataLongString (v8::Isolate* isolate,
TRI_shape_t const* shape,
char const* data,
size_t size) {
TRI_shape_length_long_string_t l;
l = * (TRI_shape_length_long_string_t const*) data;
TRI_shape_length_long_string_t l = * (TRI_shape_length_long_string_t const*) data;
data += sizeof(TRI_shape_length_long_string_t);
return TRI_V8_PAIR_STRING(data, l - 1);
@ -1448,6 +1434,7 @@ static v8::Handle<v8::Value> JsonShapeData (v8::Isolate* isolate,
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
return JsonShapeDataHomogeneousSizedList(isolate, shaper, shape, data, size);
}
{
v8::EscapableHandleScope scope(isolate);
return scope.Escape<v8::Value>(v8::Null(isolate));
@ -1853,7 +1840,6 @@ static int ObjectToJson (v8::Isolate* isolate,
for (auto it : seenObjects) {
if (parameter->StrictEquals(it)) {
// object is recursive
LOG_TRACE("found duplicate for hash %d", hash);
TRI_InitNullJson(result);
return TRI_ERROR_BAD_PARAMETER;
}