1
0
Fork 0
arangodb/SkipLists/compare.h

862 lines
29 KiB
C
Executable File

////////////////////////////////////////////////////////////////////////////////
/// @brief compare methods used for skiplist indexes
///
/// @file
///
/// DISCLAIMER
///
/// Copyright by triAGENS GmbH - All rights reserved.
///
/// The Programs (which include both the software and documentation)
/// contain proprietary information of triAGENS GmbH; they are
/// provided under a license agreement containing restrictions on use and
/// disclosure and are also protected by copyright, patent and other
/// intellectual and industrial property laws. Reverse engineering,
/// disassembly or decompilation of the Programs, except to the extent
/// required to obtain interoperability with other independently created
/// software or as specified by law, is prohibited.
///
/// The Programs are not intended for use in any nuclear, aviation, mass
/// transit, medical, or other inherently dangerous applications. It shall
/// be the licensee's responsibility to take all appropriate fail-safe,
/// backup, redundancy, and other measures to ensure the safe use of such
/// applications if the Programs are used for such purposes, and triAGENS
/// GmbH disclaims liability for any damages caused by such use of
/// the Programs.
///
/// This software is the confidential and proprietary information of
/// triAGENS GmbH. You shall not disclose such confidential and
/// proprietary information and shall use it only in accordance with the
/// terms of the license agreement you entered into with triAGENS GmbH.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. O
/// @author Copyright 2011, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_DURHAM_VOC_BASE_SKIPLIST_COMPARE_H
#define TRIAGENS_DURHAM_VOC_BASE_SKIPLIST_COMPARE_H 1
#include "ShapedJson/json-shaper.h"
#include "ShapedJson/shaped-json.h"
#include "VocBase/document-collection.h"
#define USE_STATIC_SKIPLIST_COMPARE 1
#define SKIPLIST_ELEMENT_TYPE(a,b) \
struct a { \
size_t numFields; \
TRI_shaped_json_t* fields; \
void* data; \
void* collection; \
} b
#ifdef __cplusplus
extern "C" {
#endif
static int IndexStaticCopyElementElement (TRI_skiplist_base_t* skiplist, void* left, void* right) {
typedef SKIPLIST_ELEMENT_TYPE(LocalElement_s,LocalElement_t);
LocalElement_t* leftElement = (LocalElement_t*)(left);
LocalElement_t* rightElement = (LocalElement_t*)(right);
if (leftElement == NULL || rightElement == NULL) {
assert(0);
return TRI_ERROR_INTERNAL;
}
leftElement->numFields = rightElement->numFields;
leftElement->data = rightElement->data;
leftElement->collection = rightElement->collection;
leftElement->fields = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shaped_json_t) * leftElement->numFields, false);
if (leftElement->fields == NULL) {
return TRI_ERROR_OUT_OF_MEMORY;
}
memcpy(leftElement->fields, rightElement->fields, sizeof(TRI_shaped_json_t) * leftElement->numFields);
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an element -- removing any allocated memory within the structure
////////////////////////////////////////////////////////////////////////////////
static void IndexStaticDestroyElement(TRI_skiplist_base_t* skiplist, void* element) {
typedef SKIPLIST_ELEMENT_TYPE(LocalElement_s,LocalElement_t);
// ...........................................................................
// Each 'field' in the hElement->fields is a TRI_shaped_json_t object, this
// structure has internal structure of its own -- which also has memory
// allocated -- HOWEVER we DO NOT deallocate this memory here since it
// is actually part of the document structure. This memory should be deallocated
// when the document has been destroyed.
// ...........................................................................
LocalElement_t* hElement = (LocalElement_t*)(element);
if (element != NULL) {
if (hElement->fields != NULL) {
TRI_Free(TRI_UNKNOWN_MEM_ZONE, hElement->fields);
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Helper method for recursion for CompareShapedJsonShapedJson
////////////////////////////////////////////////////////////////////////////////
// .............................................................................
// left < right return -1
// left > right return 1
// left == right return 0
// .............................................................................
static int CompareShapeTypes (const TRI_shaped_json_t* left, const TRI_shaped_json_t* right, TRI_shaper_t* leftShaper, TRI_shaper_t* rightShaper) {
int result;
size_t j;
TRI_shape_type_t leftType;
TRI_shape_type_t rightType;
const TRI_shape_t* leftShape;
const TRI_shape_t* rightShape;
size_t leftListLength;
size_t rightListLength;
size_t listLength;
TRI_shaped_json_t leftElement;
TRI_shaped_json_t rightElement;
char* leftString;
char* rightString;
leftShape = leftShaper->lookupShapeId(leftShaper, left->_sid);
rightShape = rightShaper->lookupShapeId(rightShaper, right->_sid);
leftType = leftShape->_type;
rightType = rightShape->_type;
switch (leftType) {
case TRI_SHAPE_ILLEGAL: {
switch (rightType) {
case TRI_SHAPE_ILLEGAL: {
return 0;
}
case TRI_SHAPE_NULL:
case TRI_SHAPE_BOOLEAN:
case TRI_SHAPE_NUMBER:
case TRI_SHAPE_SHORT_STRING:
case TRI_SHAPE_LONG_STRING:
case TRI_SHAPE_ARRAY:
case TRI_SHAPE_LIST:
case TRI_SHAPE_HOMOGENEOUS_LIST:
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST: {
return -1;
}
} // end of switch (rightType)
}
case TRI_SHAPE_NULL: {
switch (rightType) {
case TRI_SHAPE_ILLEGAL:
{
return 1;
}
case TRI_SHAPE_NULL:
{
return 0;
}
case TRI_SHAPE_BOOLEAN:
case TRI_SHAPE_NUMBER:
case TRI_SHAPE_SHORT_STRING:
case TRI_SHAPE_LONG_STRING:
case TRI_SHAPE_ARRAY:
case TRI_SHAPE_LIST:
case TRI_SHAPE_HOMOGENEOUS_LIST:
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
{
return -1;
}
} // end of switch (rightType)
}
case TRI_SHAPE_BOOLEAN: {
switch (rightType) {
case TRI_SHAPE_ILLEGAL:
case TRI_SHAPE_NULL:
{
return 1;
}
case TRI_SHAPE_BOOLEAN:
{
// check which is false and which is true!
if ( *((TRI_shape_boolean_t*)(left->_data.data)) == *((TRI_shape_boolean_t*)(right->_data.data)) ) {
return 0;
}
if ( *((TRI_shape_boolean_t*)(left->_data.data)) < *((TRI_shape_boolean_t*)(right->_data.data)) ) {
return -1;
}
return 1;
}
case TRI_SHAPE_NUMBER:
case TRI_SHAPE_SHORT_STRING:
case TRI_SHAPE_LONG_STRING:
case TRI_SHAPE_ARRAY:
case TRI_SHAPE_LIST:
case TRI_SHAPE_HOMOGENEOUS_LIST:
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
{
return -1;
}
} // end of switch (rightType)
}
case TRI_SHAPE_NUMBER: {
switch (rightType) {
case TRI_SHAPE_ILLEGAL:
case TRI_SHAPE_NULL:
case TRI_SHAPE_BOOLEAN:
{
return 1;
}
case TRI_SHAPE_NUMBER:
{
// compare the numbers.
if ( *((TRI_shape_number_t*)(left->_data.data)) == *((TRI_shape_number_t*)(right->_data.data)) ) {
return 0;
}
if ( *((TRI_shape_number_t*)(left->_data.data)) < *((TRI_shape_number_t*)(right->_data.data)) ) {
return -1;
}
return 1;
}
case TRI_SHAPE_SHORT_STRING:
case TRI_SHAPE_LONG_STRING:
case TRI_SHAPE_ARRAY:
case TRI_SHAPE_LIST:
case TRI_SHAPE_HOMOGENEOUS_LIST:
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
{
return -1;
}
} // end of switch (rightType)
}
case TRI_SHAPE_SHORT_STRING:
case TRI_SHAPE_LONG_STRING:
{
switch (rightType) {
case TRI_SHAPE_ILLEGAL:
case TRI_SHAPE_NULL:
case TRI_SHAPE_BOOLEAN:
case TRI_SHAPE_NUMBER:
{
return 1;
}
case TRI_SHAPE_SHORT_STRING:
case TRI_SHAPE_LONG_STRING:
{
// compare strings
// extract the strings
if (leftType == TRI_SHAPE_SHORT_STRING) {
leftString = (char*)(sizeof(TRI_shape_length_short_string_t) + left->_data.data);
}
else {
leftString = (char*)(sizeof(TRI_shape_length_long_string_t) + left->_data.data);
}
if (rightType == TRI_SHAPE_SHORT_STRING) {
rightString = (char*)(sizeof(TRI_shape_length_short_string_t) + right->_data.data);
}
else {
rightString = (char*)(sizeof(TRI_shape_length_long_string_t) + right->_data.data);
}
result = strcmp(leftString,rightString);
return result;
}
case TRI_SHAPE_ARRAY:
case TRI_SHAPE_LIST:
case TRI_SHAPE_HOMOGENEOUS_LIST:
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
{
return -1;
}
} // end of switch (rightType)
}
case TRI_SHAPE_HOMOGENEOUS_LIST:
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
case TRI_SHAPE_LIST:
{
switch (rightType) {
case TRI_SHAPE_ILLEGAL:
case TRI_SHAPE_NULL:
case TRI_SHAPE_BOOLEAN:
case TRI_SHAPE_NUMBER:
case TRI_SHAPE_SHORT_STRING:
case TRI_SHAPE_LONG_STRING:
{
return 1;
}
case TRI_SHAPE_HOMOGENEOUS_LIST:
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
case TRI_SHAPE_LIST:
{
// unfortunately recursion: check the types of all the entries
leftListLength = *((TRI_shape_length_list_t*)(left->_data.data));
rightListLength = *((TRI_shape_length_list_t*)(right->_data.data));
// determine the smallest list
if (leftListLength > rightListLength) {
listLength = rightListLength;
}
else {
listLength = leftListLength;
}
for (j = 0; j < listLength; ++j) {
if (leftType == TRI_SHAPE_HOMOGENEOUS_LIST) {
TRI_AtHomogeneousListShapedJson((const TRI_homogeneous_list_shape_t*)(leftShape),
left,j,&leftElement);
}
else if (leftType == TRI_SHAPE_HOMOGENEOUS_SIZED_LIST) {
TRI_AtHomogeneousSizedListShapedJson((const TRI_homogeneous_sized_list_shape_t*)(leftShape),
left,j,&leftElement);
}
else {
TRI_AtListShapedJson((const TRI_list_shape_t*)(leftShape),left,j,&leftElement);
}
if (rightType == TRI_SHAPE_HOMOGENEOUS_LIST) {
TRI_AtHomogeneousListShapedJson((const TRI_homogeneous_list_shape_t*)(rightShape),
right,j,&rightElement);
}
else if (rightType == TRI_SHAPE_HOMOGENEOUS_SIZED_LIST) {
TRI_AtHomogeneousSizedListShapedJson((const TRI_homogeneous_sized_list_shape_t*)(rightShape),
right,j,&rightElement);
}
else {
TRI_AtListShapedJson((const TRI_list_shape_t*)(rightShape),right,j,&rightElement);
}
result = CompareShapeTypes (&leftElement, &rightElement, leftShaper, rightShaper);
if (result != 0) {
return result;
}
}
// up to listLength everything matches
if (leftListLength < rightListLength) {
return -1;
}
else if (leftListLength > rightListLength) {
return 1;
}
return 0;
}
case TRI_SHAPE_ARRAY:
{
return -1;
}
} // end of switch (rightType)
}
case TRI_SHAPE_ARRAY:
{
/* start oreste:
char* shape = (char*)(leftShape);
uint64_t fixedEntries;
uint64_t variableEntries;
uint64_t ssid;
uint64_t aaid;
char* name;
TRI_shape_t* newShape;
shape = shape + sizeof(TRI_shape_t);
fixedEntries = *((TRI_shape_size_t*)(shape));
shape = shape + sizeof(TRI_shape_size_t);
variableEntries = *((TRI_shape_size_t*)(shape));
shape = shape + sizeof(TRI_shape_size_t);
ssid = *((TRI_shape_sid_t*)(shape));
shape = shape + (sizeof(TRI_shape_sid_t) * (fixedEntries + variableEntries));
aaid = *((TRI_shape_aid_t*)(shape));
shape = shape + (sizeof(TRI_shape_aid_t) * (fixedEntries + variableEntries));
name = leftShaper->lookupAttributeId(leftShaper,aaid);
newShape = leftShaper->lookupShapeId(leftShaper, ssid);
printf("%s:%u:_fixedEntries:%u\n",__FILE__,__LINE__,fixedEntries);
printf("%s:%u:_variableEntries:%u\n",__FILE__,__LINE__,variableEntries);
printf("%s:%u:_sids[0]:%u\n",__FILE__,__LINE__,ssid);
printf("%s:%u:_aids[0]:%u\n",__FILE__,__LINE__,aaid);
printf("%s:%u:name:%s\n",__FILE__,__LINE__,name);
printf("%s:%u:type:%d\n",__FILE__,__LINE__,newShape->_type);
end oreste */
switch (rightType) {
case TRI_SHAPE_ILLEGAL:
case TRI_SHAPE_NULL:
case TRI_SHAPE_BOOLEAN:
case TRI_SHAPE_NUMBER:
case TRI_SHAPE_SHORT_STRING:
case TRI_SHAPE_LONG_STRING:
case TRI_SHAPE_HOMOGENEOUS_LIST:
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
case TRI_SHAPE_LIST:
{
return 1;
}
case TRI_SHAPE_ARRAY:
{
assert(false);
result = 0;
return result;
}
} // end of switch (rightType)
}
}
assert(false);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Compare a shapded json object recursively if necessary
////////////////////////////////////////////////////////////////////////////////
static int CompareShapedJsonShapedJson (const TRI_shaped_json_t* left, const TRI_shaped_json_t* right, TRI_shaper_t* leftShaper, TRI_shaper_t* rightShaper) {
int result;
// ............................................................................
// the following order is currently defined for placing an order on documents
// undef < null < boolean < number < strings < lists < hash arrays
// note: undefined will be treated as NULL pointer not NULL JSON OBJECT
// within each type class we have the following order
// boolean: false < true
// number: natural order
// strings: lexicographical
// lists: lexicorgraphically and within each slot according to these rules.
// ............................................................................
if (left == NULL && right == NULL) {
return 0;
}
if (left == NULL && right != NULL) {
return -1;
}
if (left != NULL && right == NULL) {
return 1;
}
result = CompareShapeTypes (left, right, leftShaper, rightShaper);
// ............................................................................
// In the above function CompareShaeTypes we use strcmp which may return
// an integer greater than 1 or less than -1. From this function we only
// need to know whether we have equality (0), less than (-1) or greater than (1)
// ............................................................................
if (result < 0) {
result = -1;
}
else if (result > 0) {
result = 1;
}
return result;
} // end of function CompareShapedJsonShapedJson
////////////////////////////////////////////////////////////////////////////////
/// @brief compares two elements in a skip list
////////////////////////////////////////////////////////////////////////////////
static int IndexStaticCompareElementElement (struct TRI_skiplist_s* skiplist, void* leftElement, void* rightElement, int defaultEqual) {
typedef SKIPLIST_ELEMENT_TYPE(LocalElement_s,LocalElement_t);
// .............................................................................
// Compare two elements and determines:
// left < right : return -1
// left == right : return 0
// left > right : return 1
// .............................................................................
int compareResult;
LocalElement_t* hLeftElement = (LocalElement_t*)(leftElement);
LocalElement_t* hRightElement = (LocalElement_t*)(rightElement);
TRI_shaper_t* leftShaper;
TRI_shaper_t* rightShaper;
size_t j;
// ............................................................................
// the following order is currently defined for placing an order on documents
// undef < null < boolean < number < strings < lists < hash arrays
// note: undefined will be treated as NULL pointer not NULL JSON OBJECT
// within each type class we have the following order
// boolean: false < true
// number: natural order
// strings: lexicographical
// lists: lexicographically and within each slot according to these rules.
// ............................................................................
if (leftElement == NULL && rightElement == NULL) {
return 0;
}
if (leftElement != NULL && rightElement == NULL) {
return 1;
}
if (leftElement == NULL && rightElement != NULL) {
return -1;
}
if (leftElement == rightElement) {
return 0;
}
// ............................................................................
// This call back function is used when we insert and remove unique skip
// list entries.
// ............................................................................
if (hLeftElement->numFields != hRightElement->numFields) {
assert(false);
}
// ............................................................................
// The document could be the same -- so no further comparison is required.
// ............................................................................
if (hLeftElement->data == hRightElement->data) {
return 0;
}
leftShaper = ((TRI_doc_collection_t*)(hLeftElement->collection))->_shaper;
rightShaper = ((TRI_doc_collection_t*)(hRightElement->collection))->_shaper;
for (j = 0; j < hLeftElement->numFields; j++) {
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields), (j + hRightElement->fields), leftShaper, rightShaper);
if (compareResult != 0) {
return compareResult;
}
}
// ............................................................................
// This is where the difference between CompareKeyElement (below) and
// CompareElementElement comes into play. Here if the 'keys' are the same,
// but the doc ptr is different (which it is since we are here), then
// we return what was requested to be returned: 0,-1 or 1. What is returned
// depends on the purpose of calling this callback.
// ............................................................................
return defaultEqual;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief compares a key and an element
////////////////////////////////////////////////////////////////////////////////
static int IndexStaticCompareKeyElement (struct TRI_skiplist_s* skiplist, void* leftElement, void* rightElement, int defaultEqual) {
typedef SKIPLIST_ELEMENT_TYPE(LocalElement_s,LocalElement_t);
// .............................................................................
// Compare two elements and determines:
// left < right : return -1
// left == right : return 0
// left > right : return 1
// .............................................................................
int compareResult;
size_t numFields;
LocalElement_t* hLeftElement = (LocalElement_t*)(leftElement);
LocalElement_t* hRightElement = (LocalElement_t*)(rightElement);
TRI_shaper_t* leftShaper;
TRI_shaper_t* rightShaper;
size_t j;
// ............................................................................
// the following order is currently defined for placing an order on documents
// undef < null < boolean < number < strings < lists < hash arrays
// note: undefined will be treated as NULL pointer not NULL JSON OBJECT
// within each type class we have the following order
// boolean: false < true
// number: natural order
// strings: lexicographical
// lists: lexicorgraphically and within each slot according to these rules.
// associative array: ordered keys followed by value of key
// ............................................................................
if (leftElement == NULL && rightElement == NULL) {
return 0;
}
if (leftElement == NULL && rightElement != NULL) {
return -1;
}
if (leftElement != NULL && rightElement == NULL) {
return 1;
}
if (leftElement == rightElement) {
return 0;
}
// ............................................................................
// The document could be the same -- so no further comparison is required.
// ............................................................................
if (hLeftElement->data == hRightElement->data) {
return 0;
}
// ............................................................................
// This call back function is used when we query the index, as such
// the number of fields which we are using for the query may be less than
// the number of fields that the index is defined with.
// ............................................................................
if (hLeftElement->numFields < hRightElement->numFields) {
numFields = hLeftElement->numFields;
}
else {
numFields = hRightElement->numFields;
}
leftShaper = ((TRI_doc_collection_t*)(hLeftElement->collection))->_shaper;
rightShaper = ((TRI_doc_collection_t*)(hRightElement->collection))->_shaper;
for (j = 0; j < numFields; j++) {
/*
printf("%s:%u:%f:%f,%u:%u\n",__FILE__,__LINE__,
*((double*)((j + hLeftElement->fields)->_data.data)),
*((double*)((j + hRightElement->fields)->_data.data)),
(uint64_t)(hLeftElement->data),
(uint64_t)(hRightElement->data)
);
*/
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields),
(j + hRightElement->fields),
leftShaper,
rightShaper);
if (compareResult != 0) {
return compareResult;
}
}
// ............................................................................
// The 'keys' match -- however, we may only have a partial match in reality
// if not all keys comprising index have been used.
// ............................................................................
return defaultEqual;
}
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
// Non-unique skiplist
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief used to determine the order of two elements
////////////////////////////////////////////////////////////////////////////////
static int IndexStaticMultiCompareElementElement (TRI_skiplist_multi_t* multiSkiplist, void* leftElement, void* rightElement, int defaultEqual) {
typedef SKIPLIST_ELEMENT_TYPE(LocalElement_s,LocalElement_t);
int compareResult;
LocalElement_t* hLeftElement = (LocalElement_t*)(leftElement);
LocalElement_t* hRightElement = (LocalElement_t*)(rightElement);
TRI_shaper_t* leftShaper;
TRI_shaper_t* rightShaper;
size_t j;
if (leftElement == NULL && rightElement == NULL) {
return TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL;
}
if (leftElement != NULL && rightElement == NULL) {
return TRI_SKIPLIST_COMPARE_STRICTLY_GREATER;
}
if (leftElement == NULL && rightElement != NULL) {
return TRI_SKIPLIST_COMPARE_STRICTLY_LESS;
}
if (leftElement == rightElement) {
return TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL;
}
if (hLeftElement->numFields != hRightElement->numFields) {
assert(false);
}
if (hLeftElement->data == hRightElement->data) {
return TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL;
}
leftShaper = ((TRI_doc_collection_t*)(hLeftElement->collection))->_shaper;
rightShaper = ((TRI_doc_collection_t*)(hRightElement->collection))->_shaper;
for (j = 0; j < hLeftElement->numFields; j++) {
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields), (j + hRightElement->fields), leftShaper, rightShaper);
if (compareResult != 0) {
// ......................................................................
// The function CompareShaedJsonShapedJson can only return 0, -1, or 1
// that is, TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL (0)
// TRI_SKIPLIST_COMPARE_STRICTLY_LESS (-1)
// TRI_SKIPLIST_COMPARE_STRICTLY_GREATER (1)
// ......................................................................
return compareResult;
}
}
return defaultEqual;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief used to determine the order of two keys
////////////////////////////////////////////////////////////////////////////////
static int IndexStaticMultiCompareKeyElement (TRI_skiplist_multi_t* multiSkiplist, void* leftElement, void* rightElement, int defaultEqual) {
typedef SKIPLIST_ELEMENT_TYPE(LocalElement_s,LocalElement_t);
int compareResult;
size_t numFields;
LocalElement_t* hLeftElement = (LocalElement_t*)(leftElement);
LocalElement_t* hRightElement = (LocalElement_t*)(rightElement);
TRI_shaper_t* leftShaper;
TRI_shaper_t* rightShaper;
size_t j;
if (leftElement == NULL && rightElement == NULL) {
return 0;
}
if (leftElement != NULL && rightElement == NULL) {
return 1;
}
if (leftElement == NULL && rightElement != NULL) {
return -1;
}
// ............................................................................
// The document could be the same -- so no further comparison is required.
// ............................................................................
if (hLeftElement->data == hRightElement->data) {
return 0;
}
// ............................................................................
// This call back function is used when we query the index, as such
// the number of fields which we are using for the query may be less than
// the number of fields that the index is defined with.
// ............................................................................
if (hLeftElement->numFields < hRightElement->numFields) {
numFields = hLeftElement->numFields;
}
else {
numFields = hRightElement->numFields;
}
leftShaper = ((TRI_doc_collection_t*)(hLeftElement->collection))->_shaper;
rightShaper = ((TRI_doc_collection_t*)(hRightElement->collection))->_shaper;
for (j = 0; j < numFields; j++) {
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields), (j + hRightElement->fields), leftShaper, rightShaper);
if (compareResult != 0) {
return compareResult;
}
}
return defaultEqual;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief used to determine the order of two keys
////////////////////////////////////////////////////////////////////////////////
static bool IndexStaticMultiEqualElementElement (TRI_skiplist_multi_t* multiSkiplist, void* leftElement, void* rightElement) {
typedef SKIPLIST_ELEMENT_TYPE(LocalElement_s,LocalElement_t);
LocalElement_t* hLeftElement = (LocalElement_t*)(leftElement);
LocalElement_t* hRightElement = (LocalElement_t*)(rightElement);
if (leftElement == rightElement) {
return true;
}
/*
printf("%s:%u:%f:%f,%u:%u\n",__FILE__,__LINE__,
*((double*)((hLeftElement->fields)->_data.data)),
*((double*)((hRightElement->fields)->_data.data)),
(uint64_t)(hLeftElement->data),
(uint64_t)(hRightElement->data)
);
*/
return (hLeftElement->data == hRightElement->data);
}
#ifdef __cplusplus
}
#endif
#endif
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// End: