1
0
Fork 0

Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel

This commit is contained in:
Esteban Lombeyda 2014-03-31 16:12:13 +02:00
commit a62abac85d
17 changed files with 3187 additions and 2043 deletions

View File

@ -3741,7 +3741,9 @@ static int FillIndex (TRI_document_collection_t* document,
void** end;
void** ptr;
int res;
// double starttime;
//double starttime;
//extern uint64_t ALL_HASH_ADDS;
//extern uint64_t ALL_HASH_COLLS;
primary = &document->base;
@ -3755,9 +3757,7 @@ static int FillIndex (TRI_document_collection_t* document,
}
// starttime = TRI_microtime();
//printf("FillIndex _iid=%llu start time: %f\n",(unsigned long long) idx->_iid,
// starttime);
//starttime = TRI_microtime();
inserted = 0;
for (; ptr < end; ++ptr) {
@ -3787,6 +3787,8 @@ static int FillIndex (TRI_document_collection_t* document,
//printf("FillIndex _iid=%llu time spent: %f\n",(unsigned long long) idx->_iid,
// TRI_microtime()-starttime);
//printf("FillIndex adds=%llu colls=%llu\n",(unsigned long long) ALL_HASH_ADDS, (unsigned long long) ALL_HASH_COLLS);
return TRI_ERROR_NO_ERROR;
}

View File

@ -42,16 +42,12 @@
// --SECTION-- private functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup VocBase
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief find the edges index of a document collection
////////////////////////////////////////////////////////////////////////////////
static TRI_multi_pointer_t* FindEdgesIndex (TRI_document_collection_t* const document) {
static TRI_edge_index_t* FindEdgesIndex (
TRI_document_collection_t* const document) {
size_t i, n;
if (document->base.base._info._type != TRI_COL_TYPE_EDGE) {
@ -61,11 +57,11 @@ static TRI_multi_pointer_t* FindEdgesIndex (TRI_document_collection_t* const doc
n = document->_allIndexes._length;
for (i = 0; i < n; ++i) {
TRI_index_t* idx = (TRI_index_t*) TRI_AtVectorPointer(&document->_allIndexes, i);
TRI_index_t* idx
= (TRI_index_t*) TRI_AtVectorPointer(&document->_allIndexes, i);
if (idx->_type == TRI_IDX_TYPE_EDGE_INDEX) {
TRI_edge_index_t* edgesIndex = (TRI_edge_index_t*) idx;
return &edgesIndex->_edges;
return edgesIndex;
}
}
@ -74,11 +70,21 @@ static TRI_multi_pointer_t* FindEdgesIndex (TRI_document_collection_t* const doc
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return whether an edge is self-reflexive
/// @brief check whether the _from and _to end of an edge are identical
////////////////////////////////////////////////////////////////////////////////
static bool IsReflexive (const TRI_edge_header_t* const edge) {
return ((edge->_flags & TRI_EDGE_BIT_REFLEXIVE) > 0);
static bool IsReflexive (TRI_doc_mptr_t const* mptr) {
TRI_doc_edge_key_marker_t const* edge;
char* fromKey;
char* toKey;
edge = mptr->_data;
if (edge->_toCid == edge->_fromCid) {
fromKey = (char*) edge + edge->_offsetFromKey;
toKey = (char*) edge + edge->_offsetToKey;
return strcmp(fromKey, toKey) == 0;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
@ -90,17 +96,28 @@ static bool IsReflexive (const TRI_edge_header_t* const edge) {
////////////////////////////////////////////////////////////////////////////////
static bool FindEdges (const TRI_edge_direction_e direction,
TRI_multi_pointer_t* idx,
TRI_edge_index_t* idx,
TRI_vector_pointer_t* result,
TRI_edge_header_t* entry,
const int matchType) {
TRI_vector_pointer_t found;
TRI_doc_mptr_t* edge;
entry->_flags = TRI_LookupFlagsEdge(direction);
found = TRI_LookupByKeyMultiPointer(TRI_UNKNOWN_MEM_ZONE, idx, entry);
if (direction == TRI_EDGE_OUT) {
found = TRI_LookupByKeyMultiPointer(TRI_UNKNOWN_MEM_ZONE,
&idx->_edges_from,
entry);
}
else if (direction == TRI_EDGE_IN) {
found = TRI_LookupByKeyMultiPointer(TRI_UNKNOWN_MEM_ZONE,
&idx->_edges_to,
entry);
}
else {
assert(false); // TRI_EDGE_ANY not supported here
}
if (found._length > 0) {
TRI_edge_header_t* edge;
size_t i;
if (result->_capacity == 0) {
@ -119,99 +136,57 @@ static bool FindEdges (const TRI_edge_direction_e direction,
// add all results found
for (i = 0; i < found._length; ++i) {
edge = (TRI_edge_header_t*) found._buffer[i];
edge = (TRI_doc_mptr_t*) found._buffer[i];
// the following queries will use the following sequences of matchTypes:
// inEdges(): 1, 2, outEdges(): 1, 2, edges(): 1, 3
// inEdges(): 1, outEdges(): 1, edges(): 1, 3
// if matchType is 1, we'll return all found edges without further filtering
//
// if matchType is 2 (inEdges or outEdges query), the direction is reversed.
// We'll exclude all self-reflexive edges now (we already got them in iteration 1),
// if matchType is 1, we'll return all found edges without filtering
// We'll exclude all loop edges now (we already got them in iteration 1),
// and alsoexclude all unidirectional edges
//
// if matchType is 3, the direction is also reversed. We'll exclude all
// self-reflexive edges now (we already got them in iteration 1)
// loop edges now (we already got them in iteration 1)
if (matchType > 1) {
// if the edge is self-reflexive, we have already found it in iteration 1
// if the edge is a loop, we have already found it in iteration 1
// we must skip it here, otherwise we would produce duplicates
if (IsReflexive(edge)) {
continue;
}
}
TRI_PushBackVectorPointer(result, CONST_CAST(edge));
TRI_PushBackVectorPointer(result, CONST_CAST(edge->_mptr));
}
}
TRI_DestroyVectorPointer(&found);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup VocBase
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief compose edge flags aggregate out of only the direction
////////////////////////////////////////////////////////////////////////////////
TRI_edge_flags_t TRI_LookupFlagsEdge (const TRI_edge_direction_e direction) {
if (direction == TRI_EDGE_IN) {
return TRI_EDGE_BIT_DIRECTION_IN;
}
if (direction == TRI_EDGE_OUT) {
return TRI_EDGE_BIT_DIRECTION_OUT;
}
// invalid direction type
assert(false);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief compose edge flags aggregate out of multiple individual parameters
////////////////////////////////////////////////////////////////////////////////
TRI_edge_flags_t TRI_FlagsEdge (const TRI_edge_direction_e direction,
const bool isReflexive) {
TRI_edge_flags_t result = TRI_LookupFlagsEdge(direction);
if (isReflexive) {
result |= TRI_EDGE_BIT_REFLEXIVE;
}
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief looks up edges
////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t TRI_LookupEdgesDocumentCollection (TRI_document_collection_t* document,
TRI_edge_direction_e direction,
TRI_voc_cid_t cid,
TRI_voc_key_t key) {
TRI_vector_pointer_t TRI_LookupEdgesDocumentCollection (
TRI_document_collection_t* document,
TRI_edge_direction_e direction,
TRI_voc_cid_t cid,
TRI_voc_key_t key) {
TRI_vector_pointer_t result;
TRI_edge_header_t entry;
TRI_multi_pointer_t* edgesIndex;
TRI_edge_index_t* edgesIndex;
// search criteria
entry._mptr = NULL;
entry._cid = cid;
entry._searchKey._key = key;
entry._key = key;
// initialise the result vector
TRI_InitVectorPointer(&result, TRI_UNKNOWN_MEM_ZONE);
@ -240,10 +215,6 @@ TRI_vector_pointer_t TRI_LookupEdgesDocumentCollection (TRI_document_collection_
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"

View File

@ -126,10 +126,8 @@ TRI_edge_direction_e;
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_edge_header_s {
TRI_doc_mptr_t const* _mptr;
TRI_voc_cid_t _cid; // from or to, depending on the direction
union { TRI_voc_key_t _key; TRI_voc_size_t _offsetKey; } _searchKey;
TRI_edge_flags_t _flags;
TRI_voc_key_t _key;
}
TRI_edge_header_t;
@ -145,36 +143,15 @@ TRI_edge_header_t;
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup VocBase
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief compose edge flags aggregate out of only the direction
////////////////////////////////////////////////////////////////////////////////
TRI_edge_flags_t TRI_LookupFlagsEdge (const TRI_edge_direction_e);
////////////////////////////////////////////////////////////////////////////////
/// @brief compose edge flags aggregate out of multiple individual parameters
////////////////////////////////////////////////////////////////////////////////
TRI_edge_flags_t TRI_FlagsEdge (const TRI_edge_direction_e,
const bool);
////////////////////////////////////////////////////////////////////////////////
/// @brief looks up edges
////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t TRI_LookupEdgesDocumentCollection (TRI_document_collection_t*,
TRI_edge_direction_e,
TRI_voc_cid_t,
TRI_voc_key_t);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t TRI_LookupEdgesDocumentCollection (
TRI_document_collection_t*,
TRI_edge_direction_e,
TRI_voc_cid_t,
TRI_voc_key_t);
#ifdef __cplusplus
}

View File

@ -35,6 +35,8 @@
#include "BasicsC/string-buffer.h"
#include "BasicsC/tri-strings.h"
#include "BasicsC/utf8-helper.h"
#include "BasicsC/fasthash.h"
#include "BasicsC/xxhash.h"
#include "CapConstraint/cap-constraint.h"
#include "GeoIndex/geo-index.h"
#include "FulltextIndex/fulltext-index.h"
@ -688,100 +690,188 @@ void TRI_FreePrimaryIndex (TRI_index_t* idx) {
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief hashes an edge header
/// @brief hashes an edge key
////////////////////////////////////////////////////////////////////////////////
static uint64_t HashElementEdge (TRI_multi_pointer_t* array, void const* data) {
static uint64_t HashElementKey (TRI_multi_pointer_t* array, void const* data) {
TRI_edge_header_t const* h;
uint64_t hash[3];
uint64_t hash;
char* key;
h = data;
if (h->_mptr != NULL) {
key = ((char*) h->_mptr->_data) + h->_searchKey._offsetKey;
}
else {
key = h->_searchKey._key;
}
key = h->_key;
// only include directional bits for hashing, exclude special bits
hash[0] = (uint64_t) (h->_flags & TRI_EDGE_BITS_DIRECTION);
hash[1] = h->_cid;
hash[2] = TRI_FnvHashString(key);
hash = h->_cid;
hash ^= (uint64_t) fasthash64(key, strlen(key), 0x87654321);
return TRI_FnvHashPointer(hash, sizeof(hash));
return fasthash64(&hash, sizeof(hash), 0x56781234);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if key and element match
/// @brief hashes an edge (_from case)
////////////////////////////////////////////////////////////////////////////////
static bool IsEqualKeyEdge (TRI_multi_pointer_t* array,
void const* left,
void const* right) {
TRI_edge_header_t const* l;
TRI_edge_header_t const* r;
const char* lKey;
const char* rKey;
static uint64_t HashElementEdgeFrom (TRI_multi_pointer_t* array,
void const* data,
bool byKey) {
TRI_doc_mptr_t const* mptr;
TRI_doc_edge_key_marker_t const* edge;
char const* key;
l = left;
r = right;
uint64_t hash;
if (l->_mptr != NULL) {
lKey = ((char*) ((TRI_doc_edge_key_marker_t const*) l->_mptr->_data)) + l->_searchKey._offsetKey;
if (!byKey) {
hash = (uint64_t) data;
}
else {
lKey = l->_searchKey._key;
mptr = data;
edge = mptr->_data;
key = (char*) edge + edge->_offsetFromKey;
hash = edge->_fromCid;
hash ^= (uint64_t) fasthash64(key, strlen(key), 0x87654321);
}
if (r->_mptr != NULL) {
rKey = ((char*) ((TRI_doc_edge_key_marker_t const*) r->_mptr->_data)) + r->_searchKey._offsetKey;
}
else {
rKey = r->_searchKey._key;
}
// only include directional flags, exclude special bits
return ((l->_flags & TRI_EDGE_BITS_DIRECTION) == (r->_flags & TRI_EDGE_BITS_DIRECTION)) &&
(l->_cid == r->_cid) &&
(strcmp(lKey, rKey) == 0);
return fasthash64(&hash, sizeof(hash), 0x56781234);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks for elements are equal
/// @brief hashes an edge (_to case)
////////////////////////////////////////////////////////////////////////////////
static bool IsEqualElementEdge (TRI_multi_pointer_t* array,
static uint64_t HashElementEdgeTo (TRI_multi_pointer_t* array,
void const* data,
bool byKey) {
TRI_doc_mptr_t const* mptr;
TRI_doc_edge_key_marker_t const* edge;
char const* key;
uint64_t hash;
if (!byKey) {
hash = (uint64_t) data;
}
else {
mptr = data;
edge = mptr->_data;
key = (char*) edge + edge->_offsetToKey;
hash = edge->_toCid;
hash ^= (uint64_t) fasthash64(key, strlen(key), 0x87654321);
}
return fasthash64(&hash, sizeof(hash), 0x56781234);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if key and element match (_from case)
////////////////////////////////////////////////////////////////////////////////
static bool IsEqualKeyEdgeFrom (TRI_multi_pointer_t* array,
void const* left,
void const* right) {
// left is a key
// right is an element, that is a master pointer
TRI_edge_header_t const* l;
TRI_edge_header_t const* r;
TRI_doc_mptr_t const* rMptr;
TRI_doc_edge_key_marker_t const* rEdge;
const char* lKey;
const char* rKey;
l = left;
r = right;
lKey = l->_key;
if (l->_mptr != NULL) {
lKey = ((char*) ((TRI_doc_edge_key_marker_t const*) l->_mptr->_data)) + l->_searchKey._offsetKey;
rMptr = right;
rEdge = rMptr->_data;
rKey = (char*) rEdge + rEdge->_offsetFromKey;
return (strcmp(lKey, rKey) == 0) && l->_cid == rEdge->_fromCid;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if key and element match (_to case)
////////////////////////////////////////////////////////////////////////////////
static bool IsEqualKeyEdgeTo (TRI_multi_pointer_t* array,
void const* left,
void const* right) {
// left is a key
// right is an element, that is a master pointer
TRI_edge_header_t const* l;
TRI_doc_mptr_t const* rMptr;
TRI_doc_edge_key_marker_t const* rEdge;
const char* lKey;
const char* rKey;
l = left;
lKey = l->_key;
rMptr = right;
rEdge = rMptr->_data;
rKey = (char*) rEdge + rEdge->_offsetToKey;
return (strcmp(lKey, rKey) == 0) && l->_cid == rEdge->_toCid;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks for elements are equal (_from case)
////////////////////////////////////////////////////////////////////////////////
static bool IsEqualElementEdgeFrom (TRI_multi_pointer_t* array,
void const* left,
void const* right,
bool byKey) {
TRI_doc_mptr_t const* lMptr;
TRI_doc_mptr_t const* rMptr;
TRI_doc_edge_key_marker_t const* lEdge;
TRI_doc_edge_key_marker_t const* rEdge;
char const* lKey;
char const* rKey;
if (!byKey) {
return left == right;
}
else {
lKey = l->_searchKey._key;
}
lMptr = left;
rMptr = right;
lEdge = lMptr->_data;
rEdge = rMptr->_data;
lKey = (char*) lEdge + lEdge->_offsetFromKey;
rKey = (char*) rEdge + rEdge->_offsetFromKey;
if (r->_mptr != NULL) {
rKey = ((char*) ((TRI_doc_edge_key_marker_t const*) r->_mptr->_data)) + r->_searchKey._offsetKey;
return strcmp(lKey, rKey) == 0 && lEdge->_fromCid == rEdge->_fromCid;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks for elements are equal (_to case)
////////////////////////////////////////////////////////////////////////////////
static bool IsEqualElementEdgeTo (TRI_multi_pointer_t* array,
void const* left,
void const* right,
bool byKey) {
TRI_doc_mptr_t const* lMptr;
TRI_doc_mptr_t const* rMptr;
TRI_doc_edge_key_marker_t const* lEdge;
TRI_doc_edge_key_marker_t const* rEdge;
char const* lKey;
char const* rKey;
if (!byKey) {
return left == right;
}
else {
rKey = r->_searchKey._key;
}
lMptr = left;
rMptr = right;
lEdge = lMptr->_data;
rEdge = rMptr->_data;
lKey = (char*) lEdge + lEdge->_offsetToKey;
rKey = (char*) rEdge + rEdge->_offsetToKey;
// only include directional flags, exclude special bits
return (l->_mptr == r->_mptr) &&
((l->_flags & TRI_EDGE_BITS_DIRECTION) == (r->_flags & TRI_EDGE_BITS_DIRECTION)) &&
(l->_cid == r->_cid) &&
(strcmp(lKey, rKey) == 0);
return strcmp(lKey, rKey) == 0 && lEdge->_toCid == rEdge->_toCid;
}
}
////////////////////////////////////////////////////////////////////////////////
@ -791,42 +881,15 @@ static bool IsEqualElementEdge (TRI_multi_pointer_t* array,
static int InsertEdge (TRI_index_t* idx,
TRI_doc_mptr_t const* mptr,
const bool isRollback) {
TRI_edge_header_t* entryIn;
TRI_edge_header_t* entryOut;
char* memory;
TRI_doc_edge_key_marker_t const* edge;
bool isReflexive;
TRI_multi_pointer_t* edgesIndex = &(((TRI_edge_index_t*) idx)->_edges);
TRI_multi_pointer_t* edgesIndex;
edge = mptr->_data;
// is the edge self-reflexive (_from & _to are identical)?
isReflexive = (edge->_toCid == edge->_fromCid && strcmp(((char*) edge) + edge->_offsetToKey, ((char*) edge) + edge->_offsetFromKey) == 0);
// allocate memory for both edge headers and return early if memory allocation fails
memory = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, 2 * sizeof(TRI_edge_header_t), false);
if (memory == NULL) {
return TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
}
entryIn = (TRI_edge_header_t*) memory;
entryOut = (TRI_edge_header_t*) (memory + sizeof(TRI_edge_header_t));
// first slot: IN
entryIn->_mptr = mptr;
entryIn->_flags = TRI_FlagsEdge(TRI_EDGE_IN, isReflexive);
entryIn->_cid = edge->_toCid;
entryIn->_searchKey._offsetKey = edge->_offsetToKey;
TRI_InsertElementMultiPointer(edgesIndex, entryIn, true, isRollback);
// second slot: OUT
entryOut->_mptr = mptr;
entryOut->_flags = TRI_FlagsEdge(TRI_EDGE_OUT, isReflexive);
entryOut->_cid = edge->_fromCid;
entryOut->_searchKey._offsetKey = edge->_offsetFromKey;
TRI_InsertElementMultiPointer(edgesIndex, entryOut, true, isRollback);
// OUT
edgesIndex = &(((TRI_edge_index_t*) idx)->_edges_from);
TRI_InsertElementMultiPointer(edgesIndex, CONST_CAST(mptr), true, isRollback);
// IN
edgesIndex = &(((TRI_edge_index_t*) idx)->_edges_to);
TRI_InsertElementMultiPointer(edgesIndex, CONST_CAST(mptr), true, isRollback);
return TRI_ERROR_NO_ERROR;
}
@ -836,34 +899,17 @@ static int InsertEdge (TRI_index_t* idx,
////////////////////////////////////////////////////////////////////////////////
static int RemoveEdge (TRI_index_t* idx,
TRI_doc_mptr_t const* doc,
TRI_doc_mptr_t const* mptr,
const bool isRollback) {
TRI_edge_header_t entry;
TRI_edge_header_t* old;
TRI_doc_edge_key_marker_t const* edge;
TRI_multi_pointer_t* edgesIndex = &(((TRI_edge_index_t*) idx)->_edges);
edge = doc->_data;
entry._mptr = doc;
TRI_multi_pointer_t* edgesIndex;
// OUT
entry._flags = TRI_LookupFlagsEdge(TRI_EDGE_OUT);
entry._cid = edge->_fromCid;
entry._searchKey._offsetKey = edge->_offsetFromKey;
TRI_RemoveElementMultiPointer(edgesIndex, &entry);
// we do not need to free the OUT element
edgesIndex = &(((TRI_edge_index_t*) idx)->_edges_from);
TRI_RemoveElementMultiPointer(edgesIndex, mptr);
// IN
entry._flags = TRI_LookupFlagsEdge(TRI_EDGE_IN);
entry._cid = edge->_toCid;
entry._searchKey._offsetKey = edge->_offsetToKey;
old = TRI_RemoveElementMultiPointer(edgesIndex, &entry);
// the pointer to the IN element is also the memory pointer we need to free
if (old != NULL) {
TRI_Free(TRI_UNKNOWN_MEM_ZONE, old);
}
edgesIndex = &(((TRI_edge_index_t*) idx)->_edges_from);
TRI_RemoveElementMultiPointer(edgesIndex, mptr);
return TRI_ERROR_NO_ERROR;
}
@ -897,14 +943,31 @@ static TRI_json_t* JsonEdge (TRI_index_t* idx) {
static int SizeHintEdge (TRI_index_t* idx,
size_t size) {
TRI_multi_pointer_t* edgesIndex = &(((TRI_edge_index_t*) idx)->_edges);
int err;
// we assume this is called when setting up the index and the index is still empty
TRI_multi_pointer_t* edgesIndex = &(((TRI_edge_index_t*) idx)->_edges_from);
// we assume this is called when setting up the index and the index
// is still empty
assert(edgesIndex->_nrUsed == 0);
// set an initial size for the index and allow for some new nodes to be created
// set an initial size for the index for some new nodes to be created
// without resizing
return TRI_ResizeMultiPointer(edgesIndex, 2 * size + 2049);
err = TRI_ResizeMultiPointer(edgesIndex, size + 2049);
if (err != TRI_ERROR_NO_ERROR) {
return err;
}
edgesIndex = &(((TRI_edge_index_t*) idx)->_edges_to);
// we assume this is called when setting up the index and the index
// is still empty
assert(edgesIndex->_nrUsed == 0);
// set an initial size for the index for some new nodes to be created
// without resizing
return TRI_ResizeMultiPointer(edgesIndex, size + 2049);
}
////////////////////////////////////////////////////////////////////////////////
@ -938,19 +1001,31 @@ TRI_index_t* TRI_CreateEdgeIndex (struct TRI_primary_collection_s* primary,
return NULL;
}
res = TRI_InitMultiPointer(&edgeIndex->_edges,
res = TRI_InitMultiPointer(&edgeIndex->_edges_from,
TRI_UNKNOWN_MEM_ZONE,
HashElementEdge,
HashElementEdge,
IsEqualKeyEdge,
IsEqualElementEdge);
HashElementKey,
HashElementEdgeFrom,
IsEqualKeyEdgeFrom,
IsEqualElementEdgeFrom);
if (res != TRI_ERROR_NO_ERROR) {
TRI_Free(TRI_CORE_MEM_ZONE, edgeIndex);
return NULL;
}
res = TRI_InitMultiPointer(&edgeIndex->_edges_to,
TRI_UNKNOWN_MEM_ZONE,
HashElementKey,
HashElementEdgeTo,
IsEqualKeyEdgeTo,
IsEqualElementEdgeTo);
if (res != TRI_ERROR_NO_ERROR) {
TRI_DestroyMultiPointer(&edgeIndex->_edges_from);
TRI_Free(TRI_CORE_MEM_ZONE, edgeIndex);
return NULL;
}
idx = &edgeIndex->base;
@ -975,38 +1050,13 @@ TRI_index_t* TRI_CreateEdgeIndex (struct TRI_primary_collection_s* primary,
void TRI_DestroyEdgeIndex (TRI_index_t* idx) {
TRI_edge_index_t* edgesIndex;
size_t i, n;
edgesIndex = (TRI_edge_index_t*) idx;
LOG_TRACE("destroying edge index");
// free all elements in the edges index
n = (size_t) edgesIndex->_edges._nrAlloc;
// deletion from the index is done in two steps as memory was only allocated for IN edges
// the OUT edges are at memory position IN + sizeof(edge_header) and
// must not be freed themselves
// step 1: zero out all the out edges (we must not free them directly)
for (i = 0; i < n; ++i) {
TRI_edge_header_t* element = edgesIndex->_edges._table[i];
if (element != NULL && (element->_flags & TRI_EDGE_BIT_DIRECTION_OUT)) {
edgesIndex->_edges._table[i] = NULL;
}
}
// step 2: free the allocated memory
for (i = 0; i < n; ++i) {
TRI_edge_header_t* element = edgesIndex->_edges._table[i];
if (element != NULL) {
TRI_Free(TRI_UNKNOWN_MEM_ZONE, element);
}
}
TRI_DestroyMultiPointer(&edgesIndex->_edges);
TRI_DestroyMultiPointer(&edgesIndex->_edges_to);
TRI_DestroyMultiPointer(&edgesIndex->_edges_from);
TRI_DestroyVectorString(&idx->_fields);
}

View File

@ -185,7 +185,8 @@ TRI_geo_index_t;
typedef struct TRI_edge_index_s {
TRI_index_t base;
TRI_multi_pointer_t _edges;
TRI_multi_pointer_t _edges_from;
TRI_multi_pointer_t _edges_to;
}
TRI_edge_index_t;

View File

@ -4,7 +4,7 @@
# remove-on-drop = true
[server]
disable-authentication = false
disable-authentication = true
endpoint = tcp://localhost:8529
threads = 5
keyfile = UnitTests/server.pem

View File

@ -35,5 +35,5 @@ data-path = ./cluster/data
log-path = ./cluster/log
agent-path = ./bin/etcd-arango
arangod-path = ./bin/arangod
dbserver-config = ./etc/relative/arangod.conf
coordinator-config = ./etc/relative/arangod.conf
dbserver-config = ./etc/relative/arangod-dbserver.conf
coordinator-config = ./etc/relative/arangod-coordinator.conf

View File

@ -2,494 +2,492 @@
/*global window, $, Backbone, document, arangoCollectionModel*/
/*global arangoHelper,dashboardView,arangoDatabase*/
(function() {
"use strict";
(function () {
"use strict";
window.Router = Backbone.Router.extend({
routes: {
"" : "dashboard",
"dashboard" : "dashboard",
"collection/:colid" : "collection",
"collections" : "collections",
"collectionInfo/:colid" : "collectionInfo",
"new" : "newCollection",
"login" : "login",
"collection/:colid/documents/:pageid" : "documents",
"collection/:colid/:docid" : "document",
"shell" : "shell",
"query" : "query",
"logs" : "logs",
"api" : "api",
"databases" : "databases",
"application/installed/:key" : "applicationEdit",
"application/available/:key" : "applicationInstall",
"applications" : "applications",
"application/documentation/:key" : "appDocumentation",
"graph" : "graph",
"graphManagement" : "graphManagement",
"graphManagement/add" : "graphAddNew",
"graphManagement/delete/:name" : "graphDelete",
"userManagement" : "userManagement",
"userProfile" : "userProfile",
"testing" : "testview"
},
window.Router = Backbone.Router.extend({
routes: {
"": "dashboard",
"dashboard": "dashboard",
"collection/:colid": "collection",
"collections": "collections",
"collectionInfo/:colid": "collectionInfo",
"new": "newCollection",
"login": "login",
"collection/:colid/documents/:pageid": "documents",
"collection/:colid/:docid": "document",
"shell": "shell",
"query": "query",
"logs": "logs",
"api": "api",
"databases": "databases",
"application/installed/:key": "applicationEdit",
"application/available/:key": "applicationInstall",
"applications": "applications",
"application/documentation/:key": "appDocumentation",
"graph": "graph",
"graphManagement": "graphManagement",
"graphManagement/add": "graphAddNew",
"graphManagement/delete/:name": "graphDelete",
"userManagement": "userManagement",
"userProfile": "userProfile",
"testing": "testview"
},
testview: function() {
this.testView = new window.testView();
this.testView.render();
},
testview: function () {
this.testView = new window.testView();
this.testView.render();
},
initialize: function () {
this.bind('all', function(trigger, args) {
var routeData = trigger.split(":");
if (trigger === "route") {
if (this.currentRoute === "dashboard" && this.dashboardView) {
this.dashboardView.stopUpdating();
} else if (args === "dashboard") {
delete this.dashboardView;
}
this.currentRoute = args;
}
});
this.graphs = new window.GraphCollection();
this.notificationList = new window.NotificationCollection();
window.currentDB = new window.CurrentDatabase();
window.currentDB.fetch({
async: false
});
window.userCollection = new window.ArangoUsers();
window.arangoDatabase = new window.ArangoDatabase();
window.arangoCollectionsStore = new window.arangoCollections();
window.arangoDocumentsStore = new window.arangoDocuments();
window.arangoDocumentStore = new window.arangoDocument();
window.collectionsView = new window.CollectionsView({
collection: window.arangoCollectionsStore
});
window.arangoCollectionsStore.fetch();
window.documentsView = new window.DocumentsView();
window.documentView = new window.DocumentView({
collection: window.arangoDocumentStore
});
window.arangoLogsStore = new window.ArangoLogs();
window.arangoLogsStore.fetch({
success: function () {
window.logsView = new window.LogsView({
collection: window.arangoLogsStore
});
}
});
this.foxxList = new window.FoxxCollection();
this.footerView = new window.FooterView();
this.naviView = new window.NavigationView({
notificationCollection: this.notificationList,
userCollection: window.userCollection
});
this.footerView.render();
this.naviView.render();
this.graphView = new window.GraphView({
graphs: this.graphs,
collection: window.arangoCollectionsStore
});
this.initVersionCheck();
var self = this;
$(window).resize(function() {
self.handleResize();
});
//this.handleResize();
},
initVersionCheck: function () {
// this checks for version updates
var self = this;
var versionCheck = function () {
$.ajax({
async: true,
crossDomain: true,
dataType: "jsonp",
url: "https://www.arangodb.org/repositories/versions.php?callback=parseVersions",
success: function (json) {
if (typeof json !== 'object') {
return;
}
// turn our own version string into a version object
var currentVersion = window.versionHelper.fromString(self.footerView.system.version);
// get our mainline version
var mainLine = window.versionHelper.toStringMainLine(currentVersion);
var mainLines = Object.keys(json).sort(window.versionHelper.compareVersionStrings);
var latestMainLine;
mainLines.forEach(function (l) {
if (json[l].stable) {
if (window.versionHelper.compareVersionStrings(l, mainLine) > 0) {
latestMainLine = json[l];
}
}
initialize: function () {
var self = this;
this.bind('all', function (trigger, args) {
var routeData = trigger.split(":");
if (trigger === "route") {
if (self.currentRoute === "dashboard" && self.dashboardView) {
self.dashboardView.stopUpdating();
} else if (args === "dashboard") {
delete self.dashboardView;
}
self.currentRoute = args;
}
});
var update;
var mainLineVersions;
var latest;
if (latestMainLine !== undefined &&
Object.keys(latestMainLine.versions.length > 0)) {
mainLineVersions = Object.keys(latestMainLine.versions);
mainLineVersions = mainLineVersions.sort(window.versionHelper.compareVersionStrings);
latest = mainLineVersions[mainLineVersions.length - 1];
this.graphs = new window.GraphCollection();
this.notificationList = new window.NotificationCollection();
update = {
type: "major",
version: latest,
changes: latestMainLine.versions[latest].changes
};
window.currentDB = new window.CurrentDatabase();
window.currentDB.fetch({
async: false
});
window.userCollection = new window.ArangoUsers();
window.arangoDatabase = new window.ArangoDatabase();
window.arangoCollectionsStore = new window.arangoCollections();
window.arangoDocumentsStore = new window.arangoDocuments();
window.arangoDocumentStore = new window.arangoDocument();
window.collectionsView = new window.CollectionsView({
collection: window.arangoCollectionsStore
});
window.arangoCollectionsStore.fetch();
window.documentsView = new window.DocumentsView();
window.documentView = new window.DocumentView({
collection: window.arangoDocumentStore
});
window.arangoLogsStore = new window.ArangoLogs();
window.arangoLogsStore.fetch({
success: function () {
window.logsView = new window.LogsView({
collection: window.arangoLogsStore
});
}
});
this.foxxList = new window.FoxxCollection();
this.footerView = new window.FooterView();
this.naviView = new window.NavigationView({
notificationCollection: this.notificationList,
userCollection: window.userCollection
});
this.footerView.render();
this.naviView.render();
this.graphView = new window.GraphView({
graphs: this.graphs,
collection: window.arangoCollectionsStore
});
this.initVersionCheck();
$(window).resize(function () {
self.handleResize();
});
//this.handleResize();
},
initVersionCheck: function () {
// this checks for version updates
var self = this;
var versionCheck = function () {
$.ajax({
async: true,
crossDomain: true,
dataType: "jsonp",
url: "https://www.arangodb.org/repositories/versions.php" +
"?callback=parseVersions",
success: function (json) {
if (typeof json !== 'object') {
return;
}
// turn our own version string into a version object
var currentVersion =
window.versionHelper.fromString(self.footerView.system.version);
// get our mainline version
var mainLine = window.versionHelper.toStringMainLine(currentVersion);
var mainLines = Object.keys(json).
sort(window.versionHelper.compareVersionStrings);
var latestMainLine;
mainLines.forEach(function (l) {
if (json[l].stable) {
if (window.versionHelper.compareVersionStrings(l, mainLine) > 0) {
latestMainLine = json[l];
}
}
});
var update;
var mainLineVersions;
var latest;
if (latestMainLine !== undefined &&
Object.keys(latestMainLine.versions).length > 0) {
mainLineVersions = Object.keys(latestMainLine.versions);
mainLineVersions = mainLineVersions.
sort(window.versionHelper.compareVersionStrings);
latest = mainLineVersions[mainLineVersions.length - 1];
update = {
type: "major",
version: latest,
changes: latestMainLine.versions[latest].changes
};
}
// check which stable mainline versions are available remotely
if (update === undefined &&
json.hasOwnProperty(mainLine) &&
json[mainLine].stable &&
json[mainLine].hasOwnProperty("versions") &&
Object.keys(json[mainLine].versions).length > 0) {
// sort by version numbers
mainLineVersions = Object.keys(json[mainLine].versions);
mainLineVersions = mainLineVersions.
sort(window.versionHelper.compareVersionStrings);
latest = mainLineVersions[mainLineVersions.length - 1];
var result = window.versionHelper.compareVersions(
currentVersion,
window.versionHelper.fromString(latest)
);
if (result < 0) {
update = {
type: "minor",
version: latest,
changes: json[mainLine].versions[latest].changes
};
}
}
if (update !== undefined) {
var msg = "A newer version of ArangoDB (" + update.version +
") has become available. You may want to check the " +
"changelog at <a href=\"" + update.changes + "\">" +
update.changes + "</a>";
arangoHelper.arangoNotification(msg, 15000);
}
},
error: function () {
// re-schedule the version check
window.setTimeout(versionCheck, 60000);
}
});
};
window.setTimeout(versionCheck, 5000);
},
logsAllowed: function () {
return (window.currentDB.get('name') === '_system');
},
checkUser: function () {
if (window.userCollection.models.length === 0) {
this.navigate("login", {trigger: true});
return false;
}
return true;
},
login: function () {
if (!this.loginView) {
this.loginView = new window.loginView({
collection: window.userCollection
});
}
this.loginView.render();
this.naviView.selectMenuItem('');
},
collections: function () {
var naviView = this.naviView;
window.arangoCollectionsStore.fetch({
success: function () {
window.collectionsView.render();
naviView.selectMenuItem('collections-menu');
}
});
},
collection: function (colid) {
if (!this.collectionView) {
this.collectionView = new window.CollectionView();
}
this.collectionView.setColId(colid);
this.collectionView.render();
this.naviView.selectMenuItem('collections-menu');
},
collectionInfo: function (colid) {
if (!this.collectionInfoView) {
this.collectionInfoView = new window.CollectionInfoView();
}
this.collectionInfoView.setColId(colid);
this.collectionInfoView.render();
this.naviView.selectMenuItem('collections-menu');
},
newCollection: function () {
if (!this.newCollectionView) {
this.newCollectionView = new window.newCollectionView({});
}
this.newCollectionView.render();
this.naviView.selectMenuItem('collections-menu');
},
documents: function (colid, pageid) {
if (!window.documentsView) {
window.documentsView.initTable(colid, pageid);
}
window.documentsView.collectionID = colid;
var type = arangoHelper.collectionApiType(colid);
window.documentsView.colid = colid;
window.documentsView.pageid = pageid;
window.documentsView.type = type;
window.documentsView.render();
window.arangoDocumentsStore.getDocuments(colid, pageid);
},
document: function (colid, docid) {
window.documentView.colid = colid;
window.documentView.docid = docid;
window.documentView.render();
var type = arangoHelper.collectionApiType(colid);
window.documentView.type = type;
window.documentView.typeCheck(type);
},
shell: function () {
if (!this.shellView) {
this.shellView = new window.shellView();
}
this.shellView.render();
this.naviView.selectMenuItem('tools-menu');
},
query: function () {
if (!this.queryView) {
this.queryView = new window.queryView();
}
this.queryView.render();
this.naviView.selectMenuItem('query-menu');
},
api: function () {
if (!this.apiView) {
this.apiView = new window.apiView();
}
this.apiView.render();
this.naviView.selectMenuItem('tools-menu');
},
databases: function () {
if (arangoHelper.databaseAllowed() === true) {
if (!this.databaseView) {
this.databaseView = new window.databaseView({
collection: arangoDatabase
});
}
this.databaseView.render();
this.naviView.selectMenuItem('databases-menu');
}
else {
this.navigate("#", {trigger: true});
this.naviView.selectMenuItem('dashboard-menu');
$('#databaseNavi').css('display', 'none');
$('#databaseNaviSelect').css('display', 'none');
}
},
logs: function () {
if (!this.logsAllowed()) {
this.navigate('', { trigger: true });
return;
}
// check which stable mainline versions are available remotely
if (update === undefined &&
json.hasOwnProperty(mainLine) &&
json[mainLine].stable &&
json[mainLine].hasOwnProperty("versions") &&
Object.keys(json[mainLine].versions).length > 0) {
// sort by version numbers
mainLineVersions = Object.keys(json[mainLine].versions);
mainLineVersions = mainLineVersions.sort(window.versionHelper.compareVersionStrings);
latest = mainLineVersions[mainLineVersions.length - 1];
window.arangoLogsStore.fetch({
success: function () {
window.logsView.render();
$('#logNav a[href="#all"]').tab('show');
window.logsView.initLogTables();
window.logsView.drawTable();
$('#all-switch').click();
}
});
this.naviView.selectMenuItem('tools-menu');
},
var result = window.versionHelper.compareVersions(
currentVersion,
window.versionHelper.fromString(latest)
);
if (result < 0) {
update = {
type: "minor",
version: latest,
changes: json[mainLine].versions[latest].changes
};
}
dashboard: function () {
this.naviView.selectMenuItem('dashboard-menu');
if (this.statisticsDescriptionCollection === undefined) {
this.statisticsDescriptionCollection = new window.StatisticsDescriptionCollection();
this.statisticsDescriptionCollection.fetch({
async: false
});
}
if (update !== undefined) {
var msg = "A newer version of ArangoDB (" + update.version +
") has become available. You may want to check the " +
"changelog at <a href=\"" + update.changes + "\">" +
update.changes + "</a>";
// arangoHelper.arangoNotification(msg, 15000);
if (this.statistics === undefined) {
this.statisticsCollection = new window.StatisticsCollection();
}
},
error: function () {
// re-schedule the version check
window.setTimeout(versionCheck, 60000);
}
});
};
if (this.dashboardView === undefined) {
this.dashboardView = new dashboardView({
collection: this.statisticsCollection,
description: this.statisticsDescriptionCollection,
documentStore: window.arangoDocumentsStore,
dygraphConfig: window.dygraphConfig
});
}
this.dashboardView.render();
},
window.setTimeout(versionCheck, 5000);
},
graph: function () {
var self = this;
window.arangoCollectionsStore.fetch({
success: function () {
self.graphView.render();
self.naviView.selectMenuItem('graphviewer-menu');
}
});
},
logsAllowed: function () {
return (window.currentDB.get('name') === '_system');
},
graphManagement: function () {
if (!this.graphManagementView) {
this.graphManagementView =
new window.GraphManagementView({collection: this.graphs});
}
this.graphManagementView.render();
this.naviView.selectMenuItem('graphviewer-menu');
},
checkUser: function () {
if (window.userCollection.models.length === 0) {
this.navigate("login", {trigger: true});
return false;
}
return true;
},
graphAddNew: function () {
if (!this.addNewGraphView) {
this.addNewGraphView = new window.AddNewGraphView({
collection: window.arangoCollectionsStore,
graphs: this.graphs
});
}
this.addNewGraphView.render();
this.naviView.selectMenuItem('graphviewer-menu');
},
login: function () {
if (!this.loginView) {
this.loginView = new window.loginView({
collection: window.userCollection
});
}
this.loginView.render();
this.naviView.selectMenuItem('');
},
graphDelete: function (name) {
if (!this.deleteGraphView) {
this.deleteGraphView = new window.DeleteGraphView({
collection: this.graphs
});
}
this.deleteGraphView.render(name);
this.naviView.selectMenuItem('graphviewer-menu');
},
collections: function() {
var naviView = this.naviView;
window.arangoCollectionsStore.fetch({
success: function () {
window.collectionsView.render();
naviView.selectMenuItem('collections-menu');
applications: function () {
if (this.applicationsView === undefined) {
this.applicationsView = new window.ApplicationsView({
collection: this.foxxList
});
}
this.applicationsView.reload();
this.naviView.selectMenuItem('applications-menu');
},
applicationEdit: function (appkey) {
this.foxxList.fetch({
async: false
});
var editAppView = new window.foxxEditView(
{model: this.foxxList.findWhere({_key: appkey})}
);
editAppView.render();
},
applicationInstall: function (appkey) {
this.foxxList.fetch({
async: false
});
if (!this.installAppView) {
this.installAppView = new window.foxxMountView({
collection: this.foxxList
});
}
this.installAppView.render(appkey);
},
appDocumentation: function (key) {
var docuView = new window.AppDocumentationView({key: key});
docuView.render();
this.naviView.selectMenuItem('applications-menu');
},
handleSelectDatabase: function () {
this.naviView.handleSelectDatabase();
},
handleResize: function () {
if (this.dashboardView) {
this.dashboardView.resize();
}
var oldWidth = $('#content').width();
var containerWidth = $(window).width() - 70;
/*var spanWidth = 242;*/
var spanWidth = 243;
var divider = containerWidth / spanWidth;
var roundDiv = parseInt(divider, 10);
var newWidth = roundDiv * spanWidth - 2;
var marginWidth = ((containerWidth + 30) - newWidth) / 2;
/*
$('#content').width(newWidth)
.css('margin-left', marginWidth)
.css('margin-right', marginWidth);
*/
// $('.footer-right p').css('margin-right', marginWidth + 20);
// $('.footer-left p').css('margin-left', marginWidth + 20);
if (newWidth !== oldWidth) {
this.graphView.handleResize(newWidth);
}
},
userManagement: function () {
if (!this.userManagementView) {
this.userManagementView = new window.userManagementView({
collection: window.userCollection
});
}
this.userManagementView.render();
this.naviView.selectMenuItem('tools-menu');
},
userProfile: function () {
if (!this.userProfileView) {
this.userProfileView = new window.userProfileView({
collection: window.userCollection
});
}
this.userProfileView.render();
this.naviView.selectMenuItem('user-menu');
}
});
},
collection: function(colid) {
if (!this.collectionView) {
this.collectionView = new window.CollectionView();
}
this.collectionView.setColId(colid);
this.collectionView.render();
this.naviView.selectMenuItem('collections-menu');
},
collectionInfo: function(colid) {
if (!this.collectionInfoView) {
this.collectionInfoView = new window.CollectionInfoView();
}
this.collectionInfoView.setColId(colid);
this.collectionInfoView.render();
this.naviView.selectMenuItem('collections-menu');
},
newCollection: function() {
if (!this.newCollectionView) {
this.newCollectionView = new window.newCollectionView({});
}
this.newCollectionView.render();
this.naviView.selectMenuItem('collections-menu');
},
documents: function(colid, pageid) {
if (!window.documentsView) {
window.documentsView.initTable(colid, pageid);
}
window.documentsView.collectionID = colid;
var type = arangoHelper.collectionApiType(colid);
window.documentsView.colid = colid;
window.documentsView.pageid = pageid;
window.documentsView.type = type;
window.documentsView.render();
window.arangoDocumentsStore.getDocuments(colid, pageid);
},
document: function(colid, docid) {
window.documentView.colid = colid;
window.documentView.docid = docid;
window.documentView.render();
var type = arangoHelper.collectionApiType(colid);
window.documentView.type = type;
window.documentView.typeCheck(type);
},
shell: function() {
if (!this.shellView) {
this.shellView = new window.shellView();
}
this.shellView.render();
this.naviView.selectMenuItem('tools-menu');
},
query: function() {
if (!this.queryView) {
this.queryView = new window.queryView();
}
this.queryView.render();
this.naviView.selectMenuItem('query-menu');
},
api: function() {
if (!this.apiView) {
this.apiView = new window.apiView();
}
this.apiView.render();
this.naviView.selectMenuItem('tools-menu');
},
databases: function() {
if (arangoHelper.databaseAllowed() === true) {
if (!this.databaseView) {
this.databaseView = new window.databaseView({
collection: arangoDatabase
});
}
this.databaseView.render();
this.naviView.selectMenuItem('databases-menu');
}
else {
this.navigate("#", {trigger: true});
this.naviView.selectMenuItem('dashboard-menu');
$('#databaseNavi').css('display','none');
$('#databaseNaviSelect').css('display','none');
}
},
logs: function() {
if (! this.logsAllowed()) {
this.navigate('', { trigger: true });
return;
}
window.arangoLogsStore.fetch({
success: function () {
window.logsView.render();
$('#logNav a[href="#all"]').tab('show');
window.logsView.initLogTables();
window.logsView.drawTable();
$('#all-switch').click();
}
});
this.naviView.selectMenuItem('tools-menu');
},
dashboard: function() {
this.naviView.selectMenuItem('dashboard-menu');
if (this.statisticsDescriptionCollection === undefined) {
this.statisticsDescriptionCollection = new window.StatisticsDescriptionCollection();
this.statisticsDescriptionCollection.fetch({
async:false
});
}
if (this.statistics === undefined) {
this.statisticsCollection = new window.StatisticsCollection();
}
if (this.dashboardView === undefined) {
this.dashboardView = new dashboardView({
collection: this.statisticsCollection,
description: this.statisticsDescriptionCollection,
documentStore: window.arangoDocumentsStore,
dygraphConfig : window.dygraphConfig
});
}
this.dashboardView.render();
},
graph: function() {
var self = this;
window.arangoCollectionsStore.fetch({
success: function () {
self.graphView.render();
self.naviView.selectMenuItem('graphviewer-menu');
}
});
},
graphManagement: function() {
if (!this.graphManagementView) {
this.graphManagementView = new window.GraphManagementView({collection: this.graphs});
}
this.graphManagementView.render();
this.naviView.selectMenuItem('graphviewer-menu');
},
graphAddNew: function() {
if (!this.addNewGraphView) {
this.addNewGraphView = new window.AddNewGraphView({
collection: window.arangoCollectionsStore,
graphs: this.graphs
});
}
this.addNewGraphView.render();
this.naviView.selectMenuItem('graphviewer-menu');
},
graphDelete: function(name) {
if (!this.deleteGraphView) {
this.deleteGraphView = new window.DeleteGraphView({
collection: this.graphs
});
}
this.deleteGraphView.render(name);
this.naviView.selectMenuItem('graphviewer-menu');
},
applications: function() {
if (this.applicationsView === undefined) {
this.applicationsView = new window.ApplicationsView({
collection: this.foxxList
});
}
this.applicationsView.reload();
this.naviView.selectMenuItem('applications-menu');
},
applicationEdit: function(appkey) {
this.foxxList.fetch({
async: false
});
var editAppView = new window.foxxEditView({model: this.foxxList.findWhere({_key: appkey})});
editAppView.render();
},
applicationInstall: function(appkey) {
this.foxxList.fetch({
async: false
});
if (!this.installAppView) {
this.installAppView = new window.foxxMountView({
collection: this.foxxList
});
}
this.installAppView.render(appkey);
},
appDocumentation: function(key) {
var docuView = new window.AppDocumentationView({key: key});
docuView.render();
this.naviView.selectMenuItem('applications-menu');
},
handleSelectDatabase: function () {
this.naviView.handleSelectDatabase();
},
handleResize: function () {
if (this.dashboardView) {
this.dashboardView.resize();
}
var oldWidth = $('#content').width();
var containerWidth = $(window).width() - 70;
/*var spanWidth = 242;*/
var spanWidth = 243;
var divider = containerWidth / spanWidth;
var roundDiv = parseInt(divider, 10);
var newWidth = roundDiv*spanWidth -2;
var marginWidth = ((containerWidth+30) - newWidth)/2;
/*
$('#content').width(newWidth)
.css('margin-left', marginWidth)
.css('margin-right', marginWidth);
*/
// $('.footer-right p').css('margin-right', marginWidth + 20);
// $('.footer-left p').css('margin-left', marginWidth + 20);
if (newWidth !== oldWidth) {
this.graphView.handleResize(newWidth);
}
},
userManagement: function() {
if (!this.userManagementView) {
this.userManagementView = new window.userManagementView({
collection: window.userCollection
});
}
this.userManagementView.render(false);
this.naviView.selectMenuItem('tools-menu');
},
userProfile: function() {
if (!this.userManagementView) {
this.userManagementView = new window.userManagementView({
collection: window.userCollection
});
}
this.userManagementView.render(true);
this.naviView.selectMenuItem('tools-menu');
}
/*
userProfile: function() {
if (!this.userProfileView) {
this.userProfileView = new window.userProfileView({
collection: window.userCollection
});
}
this.userProfileView.render();
this.naviView.selectMenuItem('user-menu');
}
*/
});
});
}());

View File

@ -143,7 +143,9 @@
"frontend/js/views/foxxActiveView.js",
"frontend/js/views/foxxInstalledView.js",
"frontend/js/views/foxxEditView.js",
"frontend/js/views/databaseView.js",
"frontend/js/views/foxxMountView.js",
"frontend/js/views/testView.js",
"frontend/js/views/appDocumentationView.js",
"frontend/js/views/graphView.js",
"frontend/js/views/graphManagementView.js",
@ -159,6 +161,9 @@
"frontend/js/views/clusterDatabaseView.js",
"frontend/js/views/clusterCollectionView.js",
"frontend/js/views/clusterShardsView.js",
"frontend/js/views/userManagementView.js",
"frontend/js/views/userProfileView.js",
"frontend/js/views/userBarView.js",
"frontend/js/views/statisticBarView.js",
"frontend/js/views/userBarView.js",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,7 @@
/// @author Dr. Frank Celler
/// @author Martin Schoenert
/// @author Dr. Oreste Costa-Panaia
/// @author Max Neunhoeffer
/// @author Copyright 2006-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
@ -39,152 +40,6 @@
extern "C" {
#endif
// -----------------------------------------------------------------------------
// --SECTION-- MULTI ASSOCIATIVE ARRAY
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Collections
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief associative multi array
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_multi_array_s {
uint64_t (*hashKey) (struct TRI_multi_array_s*, void*);
uint64_t (*hashElement) (struct TRI_multi_array_s*, void*);
void (*clearElement) (struct TRI_multi_array_s*, void*);
bool (*isEmptyElement) (struct TRI_multi_array_s*, void*);
bool (*isEqualKeyElement) (struct TRI_multi_array_s*, void*, void*);
bool (*isEqualElementElement) (struct TRI_multi_array_s*, void*, void*);
uint32_t _elementSize; // the size of the elements which are to be stored in the table
uint64_t _nrAlloc; // the size of the table
uint64_t _nrUsed; // the number of used entries
char* _table; // the table itself
#ifdef TRI_INTERNAL_STATS
uint64_t _nrFinds; // statistics: number of lookup calls
uint64_t _nrAdds; // statistics: number of insert calls
uint64_t _nrRems; // statistics: number of remove calls
uint64_t _nrResizes; // statistics: number of resizes
uint64_t _nrProbesF; // statistics: number of misses while looking up
uint64_t _nrProbesA; // statistics: number of misses while inserting
uint64_t _nrProbesD; // statistics: number of misses while removing
uint64_t _nrProbesR; // statistics: number of misses while adding
#endif
TRI_memory_zone_t* _memoryZone;
}
TRI_multi_array_t;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Collections
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief initialises an array
////////////////////////////////////////////////////////////////////////////////
int TRI_InitMultiArray (TRI_multi_array_t*,
TRI_memory_zone_t*,
size_t elementSize,
uint64_t (*hashKey) (TRI_multi_array_t*, void*),
uint64_t (*hashElement) (TRI_multi_array_t*, void*),
void (*clearElement) (TRI_multi_array_t*, void*),
bool (*isEmptyElement) (TRI_multi_array_t*, void*),
bool (*isEqualKeyElement) (TRI_multi_array_t*, void*, void*),
bool (*isEqualElementElement) (TRI_multi_array_t*, void*, void*));
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an array, but does not free the pointer
////////////////////////////////////////////////////////////////////////////////
void TRI_DestroyMultiArray (TRI_multi_array_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an array and frees the pointer
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeMultiArray (TRI_memory_zone_t*, TRI_multi_array_t*);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Collections
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief lookups an element given a key
////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t TRI_LookupByKeyMultiArray (TRI_memory_zone_t*,
TRI_multi_array_t*,
void* key);
////////////////////////////////////////////////////////////////////////////////
/// @brief lookups an element given an element
////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t TRI_LookupByElementMultiArray (TRI_memory_zone_t*,
TRI_multi_array_t*,
void* element);
////////////////////////////////////////////////////////////////////////////////
/// @brief adds an element to the array
////////////////////////////////////////////////////////////////////////////////
bool TRI_InsertElementMultiArray (TRI_multi_array_t*, void* element, bool overwrite);
////////////////////////////////////////////////////////////////////////////////
/// @brief adds an key/element to the array
////////////////////////////////////////////////////////////////////////////////
bool TRI_InsertKeyMultiArray (TRI_multi_array_t*, void* key, void* element, bool overwrite);
////////////////////////////////////////////////////////////////////////////////
/// @brief removes an element from the array
////////////////////////////////////////////////////////////////////////////////
bool TRI_RemoveElementMultiArray (TRI_multi_array_t*, void* element, void* old);
////////////////////////////////////////////////////////////////////////////////
/// @brief removes an key/element to the array
////////////////////////////////////////////////////////////////////////////////
bool TRI_RemoveKeyMultiArray (TRI_multi_array_t*, void* key, void* old);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- MULTI ASSOCIATIVE POINTERS
// -----------------------------------------------------------------------------
@ -194,25 +49,73 @@ bool TRI_RemoveKeyMultiArray (TRI_multi_array_t*, void* key, void* old);
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Collections
/// @{
/// @brief associative multi array of pointers
///
/// This is a data structure that can store pointers to objects. Each object
/// has a unique key (for example a certain attribute) and multiple
/// objects in the associative array can have the same key. Every object
/// can be at most once in the array.
/// We want to offer constant time complexity for the following
/// operations:
/// - insert pointer to an object into the array
/// - lookup pointer to an object in the array
/// - delete pointer to an object from the array
/// - find one pointer to an object with a given key
/// Furthermore, we want to offer O(n) complexity for the following
/// operation:
/// - find all pointers whose objects have a given key k, where n is
/// the number of objects in the array with this key
/// To this end, we use a hash table and ask the user to provide the following:
/// - a way to hash objects by keys, and to hash keys themselves,
/// - a way to hash objects by their full identity
/// - a way to compare a key to the key of a given object
/// - a way to compare two elements, either by their keys or by their full
/// identities.
/// To avoid unnecessary comparisons the user can guarantee that s/he will
/// only try to store non-identical elements into the array. This enables
/// the code to skip comparisons which would otherwise be necessary to
/// ensure uniqueness.
/// The idea of the algorithm is as follows: Each slot in the hash table
/// contains a pointer to the actual object, as well as two unsigned
/// integers "prev" and "next" (being indices in the hash table) to
/// organise a linked list of entries, *within the same hash table*. All
/// objects with the same key are kept in a doubly linked list. The first
/// element in such a linked list is kept at the position determined by
/// its hash with respect to its key (or in the first free slot after this
/// position). All further elements in such a linked list are kept at the
/// position determined by its hash with respect to its full identity
/// (or in the first free slot after this position). Provided the hash
/// table is large enough and the hash functions distribute well enough,
/// this gives the proposed complexity.
///
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief associative multi array of pointers
////////////////////////////////////////////////////////////////////////////////
typedef uint64_t TRI_multi_pointer_index_t;
#define TRI_MULTI_POINTER_INVALID_INDEX (((TRI_multi_pointer_index_t)0)-1)
typedef struct TRI_multi_pointer_entry_s {
void* ptr; // a pointer to the data stored in this slot
TRI_multi_pointer_index_t next; // index of the data following in the linked
// list of all items with the same key
TRI_multi_pointer_index_t prev; // index of the data preceding in the linked
// list of all items with the same key
} TRI_multi_pointer_entry_t;
typedef struct TRI_multi_pointer_s {
uint64_t (*hashKey) (struct TRI_multi_pointer_s*, void const*);
uint64_t (*hashElement) (struct TRI_multi_pointer_s*, void const*);
uint64_t (*hashKey) (struct TRI_multi_pointer_s*, void const* key);
uint64_t (*hashElement) (struct TRI_multi_pointer_s*, void const* element,
bool byKey);
bool (*isEqualKeyElement) (struct TRI_multi_pointer_s*, void const*, void const*);
bool (*isEqualElementElement) (struct TRI_multi_pointer_s*, void const*, void const*);
bool (*isEqualKeyElement) (struct TRI_multi_pointer_s*, void const* key,
void const* element);
bool (*isEqualElementElement) (struct TRI_multi_pointer_s*,
void const* el1, void const* el2, bool byKey);
uint64_t _nrAlloc; // the size of the table
uint64_t _nrUsed; // the number of used entries
void** _table; // the table itself
TRI_multi_pointer_entry_t* _table_alloc; // the table itself
TRI_multi_pointer_entry_t* _table; // the table itself, 64 aligned
#ifdef TRI_INTERNAL_STATS
uint64_t _nrFinds; // statistics: number of lookup calls
@ -220,39 +123,36 @@ typedef struct TRI_multi_pointer_s {
uint64_t _nrRems; // statistics: number of remove calls
uint64_t _nrResizes; // statistics: number of resizes
uint64_t _nrProbes; // statistics: number of misses in FindElementPlace
// and LookupByElement, used by insert, lookup and
// remove
uint64_t _nrProbesF; // statistics: number of misses while looking up
uint64_t _nrProbesA; // statistics: number of misses while inserting
uint64_t _nrProbesD; // statistics: number of misses while removing
uint64_t _nrProbesR; // statistics: number of misses while adding
#endif
TRI_memory_zone_t* _memoryZone;
}
TRI_multi_pointer_t;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Collections
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief initialises an array
////////////////////////////////////////////////////////////////////////////////
int TRI_InitMultiPointer (TRI_multi_pointer_t* array,
TRI_memory_zone_t*,
uint64_t (*hashKey) (TRI_multi_pointer_t*, void const*),
uint64_t (*hashElement) (TRI_multi_pointer_t*, void const*),
bool (*isEqualKeyElement) (TRI_multi_pointer_t*, void const*, void const*),
bool (*isEqualElementElement) (TRI_multi_pointer_t*, void const*, void const*));
uint64_t (*hashKey) (TRI_multi_pointer_t*,
void const*),
uint64_t (*hashElement) (TRI_multi_pointer_t*,
void const*, bool),
bool (*isEqualKeyElement) (TRI_multi_pointer_t*,
void const*, void const*),
bool (*isEqualElementElement) (TRI_multi_pointer_t*,
void const*,
void const*, bool));
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an array, but does not free the pointer
@ -266,19 +166,10 @@ void TRI_DestroyMultiPointer (TRI_multi_pointer_t*);
void TRI_FreeMultiPointer (TRI_memory_zone_t*, TRI_multi_pointer_t*);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Collections
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief lookups an element given a key
////////////////////////////////////////////////////////////////////////////////
@ -291,16 +182,17 @@ TRI_vector_pointer_t TRI_LookupByKeyMultiPointer (TRI_memory_zone_t*,
/// @brief lookups an element given an element
////////////////////////////////////////////////////////////////////////////////
void* TRI_LookupByElementMultiPointer (TRI_multi_pointer_t*, void const* element);
void* TRI_LookupByElementMultiPointer (TRI_multi_pointer_t*,
void const* element);
////////////////////////////////////////////////////////////////////////////////
/// @brief adds an key/element to the array
/// @brief adds a key/element to the array
////////////////////////////////////////////////////////////////////////////////
void* TRI_InsertElementMultiPointer (TRI_multi_pointer_t*,
void*,
const bool,
const bool);
bool const overwrite,
bool const checkEquality);
////////////////////////////////////////////////////////////////////////////////
/// @brief removes an element from the array
@ -314,10 +206,189 @@ void* TRI_RemoveElementMultiPointer (TRI_multi_pointer_t*, void const* element);
int TRI_ResizeMultiPointer (TRI_multi_pointer_t*, size_t);
// -----------------------------------------------------------------------------
// --SECTION-- MULTI ASSOCIATIVE POINTERS WITH MULTIPLE KEYS
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @}
/// @brief associative multi array of pointers with multiple keys
///
/// This is a data structure that can store pairs (p,h) where p is a
/// pointer to an object and h is a pointer to something identifying
/// one of the keys of the object. Each object has one ore more keys
/// (for example multiple values in a list in a certain attribute) and
/// multiple objects in the associative array can have the same key.
/// Every pair (p,h) can be at most once in the array.
/// We want to offer constant time complexity for the following
/// operations:
/// - insert a pair into the array
/// - delete a pair from the array
/// - find one pair (p,h) with a given key k
/// Furthermore, we want to offer O(n) complexity for the following
/// operation:
/// - find the list of pointers p for which there is at least one pair
/// (p,h) in the array, where n is the number of objects in the array
/// with the given key k
/// To this end, we use a hash table and ask the user to provide the following:
/// - a way to hash a pair (p,h) by its full identity
/// - a way to hash a pair (p,h) but only with respect to its key k
/// - a way to hash a given key k
/// - a way to compare the key of a pair (p,h) with an external key k
/// - a way to compare the keys of two pairs (p,h) and (p',h')
/// - a way to compare two pairs (p,h) and (p',h')
/// To avoid unnecessary comparisons the user can guarantee that s/he will
/// only try to store non-identical pairs into the array. This enables
/// the code to skip comparisons which would otherwise be necessary to
/// ensure uniqueness.
/// The idea of the algorithm is as follows: Each slot in the hash table
/// contains a pointer to the actual object, a pointer to its key helper, as
/// well as two unsigned integers "prev" and "next" (being indices in
/// the hash table) to organise a linked list of entries, *within the
/// same hash table*. All pairs with the same key are kept in a doubly
/// linked list. The first element in such a linked list is kept at the
/// position determined by the hash of its key (or in the first free
/// slot after this position). All further pairs in such a linked list
/// are kept at the position determined by the hash of the pair. (or in
/// the first free slot after this position). Provided the hash table
/// is large enough and the hash functions distribute well enough, this
/// gives the proposed complexity.
///
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_multi_pair_entry_s {
void* ptr; // a pointer to the data stored in this slot
void* key; // a pointer to the helper to find the key stored in this slot
TRI_multi_pointer_index_t next; // index of the data following in the linked
// list of all items with the same key
TRI_multi_pointer_index_t prev; // index of the data preceding in the linked
// list of all items with the same key
} TRI_multi_pair_entry_t;
typedef struct TRI_multi_pair_s {
uint64_t (*hashKeyKey) (struct TRI_multi_pair_s*, void const* key);
uint64_t (*hashKeyPair) (struct TRI_multi_pair_s*,
void const* element, void const* keyhelper);
uint64_t (*hashPair) (struct TRI_multi_pair_s*,
void const* element, void const* keyhelper);
bool (*isEqualKeyPairKey) (struct TRI_multi_pair_s*,
void const* element, void const* keyhelper,
void const* key);
bool (*isEqualKeyPairPair) (struct TRI_multi_pair_s*,
void const* element1, void const* keyhelper1,
void const* element2, void const* keyhelper2);
bool (*isEqualPairPair) (struct TRI_multi_pair_s*,
void const* element1, void const* keyhelper1,
void const* element2, void const* keyhelper2);
uint64_t _nrAlloc; // the size of the table
uint64_t _nrUsed; // the number of used entries
TRI_multi_pair_entry_t* _table; // the table itself
#ifdef TRI_INTERNAL_STATS
uint64_t _nrFinds; // statistics: number of lookup calls
uint64_t _nrAdds; // statistics: number of insert calls
uint64_t _nrRems; // statistics: number of remove calls
uint64_t _nrResizes; // statistics: number of resizes
uint64_t _nrProbes; // statistics: number of misses in FindPairPlace
// and LookupByPair, used by insert, lookup and
// remove
uint64_t _nrProbesF; // statistics: number of misses while looking up
uint64_t _nrProbesD; // statistics: number of misses while removing
#endif
TRI_memory_zone_t* _memoryZone;
}
TRI_multi_pair_t;
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief initialises an array
////////////////////////////////////////////////////////////////////////////////
int TRI_InitMultiPair (
TRI_multi_pair_t* array,
TRI_memory_zone_t*,
uint64_t (*hashKeyKey) (struct TRI_multi_pair_s*, void const* key),
uint64_t (*hashKeyPair) (struct TRI_multi_pair_s*,
void const* element, void const* keyhelper),
uint64_t (*hashPair) (struct TRI_multi_pair_s*,
void const* element, void const* keyhelper),
bool (*isEqualKeyPairKey) (struct TRI_multi_pair_s*,
void const* element, void const* keyhelper,
void const* key),
bool (*isEqualKeyPairPair) (struct TRI_multi_pair_s*,
void const* element1, void const* keyhelper1,
void const* element2, void const* keyhelper2),
bool (*isEqualPairPair) (struct TRI_multi_pair_s*,
void const* element1, void const* keyhelper1,
void const* element2, void const* keyhelper2));
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an array, but does not free the pointer
////////////////////////////////////////////////////////////////////////////////
void TRI_DestroyMultiPair (TRI_multi_pair_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an array and frees the pointer
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeMultiPair (TRI_memory_zone_t*, TRI_multi_pair_t*);
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief lookups an element given a key
////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t TRI_LookupByKeyMultiPair (TRI_memory_zone_t*,
TRI_multi_pair_t*,
void const* key);
////////////////////////////////////////////////////////////////////////////////
/// @brief adds a pair to the array
////////////////////////////////////////////////////////////////////////////////
void* TRI_InsertPairMultiPair (TRI_multi_pair_t*,
void* element,
void* keyhelper,
bool const overwrite,
bool const checkEquality);
////////////////////////////////////////////////////////////////////////////////
/// @brief looks up a pair in the array
////////////////////////////////////////////////////////////////////////////////
void* TRI_LookupPairMultiPair (TRI_multi_pair_t*,
void* element,
void* keyhelper);
////////////////////////////////////////////////////////////////////////////////
/// @brief removes pair from the array
////////////////////////////////////////////////////////////////////////////////
void* TRI_RemovePairMultiPair (TRI_multi_pair_t*,
void const* element,
void const* keyhelper);
////////////////////////////////////////////////////////////////////////////////
/// @brief resize the array
////////////////////////////////////////////////////////////////////////////////
int TRI_ResizeMultiPair (TRI_multi_pair_t*, size_t);
#ifdef __cplusplus
}
#endif

75
lib/BasicsC/fasthash.c Normal file
View File

@ -0,0 +1,75 @@
/* The MIT License
Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com)
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "fasthash.h"
// Compression function for Merkle-Damgard construction.
// This function is generated using the framework provided.
#define mix(h) ({ \
(h) ^= (h) >> 23; \
(h) *= 0x2127599bf4325c37ULL; \
(h) ^= (h) >> 47; })
uint64_t fasthash64(const void *buf, size_t len, uint64_t seed)
{
const uint64_t m = 0x880355f21e6d1965ULL;
const uint64_t *pos = (const uint64_t *)buf;
const uint64_t *end = pos + (len / 8);
const unsigned char *pos2;
uint64_t h = seed ^ (len * m);
uint64_t v;
while (pos != end) {
v = *pos++;
h ^= mix(v);
h *= m;
}
pos2 = (const unsigned char*)pos;
v = 0;
switch (len & 7) {
case 7: v ^= (uint64_t)pos2[6] << 48;
case 6: v ^= (uint64_t)pos2[5] << 40;
case 5: v ^= (uint64_t)pos2[4] << 32;
case 4: v ^= (uint64_t)pos2[3] << 24;
case 3: v ^= (uint64_t)pos2[2] << 16;
case 2: v ^= (uint64_t)pos2[1] << 8;
case 1: v ^= (uint64_t)pos2[0];
h ^= mix(v);
h *= m;
}
return mix(h);
}
uint32_t fasthash32(const void *buf, size_t len, uint32_t seed)
{
// the following trick converts the 64-bit hashcode to Fermat
// residue, which shall retain information from both the higher
// and lower parts of hashcode.
uint64_t h = fasthash64(buf, len, seed);
return h - (h >> 32);
}

56
lib/BasicsC/fasthash.h Normal file
View File

@ -0,0 +1,56 @@
/* The MIT License
Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com)
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _FASTHASH_H
#define _FASTHASH_H
#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* fasthash32 - 32-bit implementation of fasthash
* @buf: data buffer
* @len: data size
* @seed: the seed
*/
uint32_t fasthash32(const void *buf, size_t len, uint32_t seed);
/**
* fasthash64 - 64-bit implementation of fasthash
* @buf: data buffer
* @len: data size
* @seed: the seed
*/
uint64_t fasthash64(const void *buf, size_t len, uint64_t seed);
#ifdef __cplusplus
}
#endif
#endif

475
lib/BasicsC/xxhash.c Normal file
View File

@ -0,0 +1,475 @@
/*
xxHash - Fast Hash algorithm
Copyright (C) 2012-2014, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at :
- xxHash source repository : http://code.google.com/p/xxhash/
*/
//**************************************
// Tuning parameters
//**************************************
// Unaligned memory access is automatically enabled for "common" CPU, such as x86.
// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected.
// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance.
// You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32).
#if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
# define XXH_USE_UNALIGNED_ACCESS 1
#endif
// XXH_ACCEPT_NULL_INPUT_POINTER :
// If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
// When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
// This option has a very small performance cost (only measurable on small inputs).
// By default, this option is disabled. To enable it, uncomment below define :
//#define XXH_ACCEPT_NULL_INPUT_POINTER 1
// XXH_FORCE_NATIVE_FORMAT :
// By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
// Results are therefore identical for little-endian and big-endian CPU.
// This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
// Should endian-independance be of no importance for your application, you may set the #define below to 1.
// It will improve speed for Big-endian CPU.
// This option has no impact on Little_Endian CPU.
#define XXH_FORCE_NATIVE_FORMAT 0
//**************************************
// Compiler Specific Options
//**************************************
// Disable some Visual warning messages
#ifdef _MSC_VER // Visual Studio
# pragma warning(disable : 4127) // disable: C4127: conditional expression is constant
#endif
#ifdef _MSC_VER // Visual Studio
# define FORCE_INLINE static __forceinline
#else
# ifdef __GNUC__
# define FORCE_INLINE static inline __attribute__((always_inline))
# else
# define FORCE_INLINE static inline
# endif
#endif
//**************************************
// Includes & Memory related functions
//**************************************
#include "xxhash.h"
// Modify the local functions below should you wish to use some other memory related routines
// for malloc(), free()
#include <stdlib.h>
FORCE_INLINE void* XXH_malloc(size_t s) { return malloc(s); }
FORCE_INLINE void XXH_free (void* p) { free(p); }
// for memcpy()
#include <string.h>
FORCE_INLINE void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
//**************************************
// Basic Types
//**************************************
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99
# include <stdint.h>
typedef uint8_t BYTE;
typedef uint16_t U16;
typedef uint32_t U32;
typedef int32_t S32;
typedef uint64_t U64;
#else
typedef unsigned char BYTE;
typedef unsigned short U16;
typedef unsigned int U32;
typedef signed int S32;
typedef unsigned long long U64;
#endif
#if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS)
# define _PACKED __attribute__ ((packed))
#else
# define _PACKED
#endif
#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
# ifdef __IBMC__
# pragma pack(1)
# else
# pragma pack(push, 1)
# endif
#endif
typedef struct _U32_S { U32 v; } _PACKED U32_S;
#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
# pragma pack(pop)
#endif
#define A32(x) (((U32_S *)(x))->v)
//***************************************
// Compiler-specific Functions and Macros
//***************************************
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
// Note : although _rotl exists for minGW (GCC under windows), performance seems poor
#if defined(_MSC_VER)
# define XXH_rotl32(x,r) _rotl(x,r)
#else
# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
#endif
#if defined(_MSC_VER) // Visual Studio
# define XXH_swap32 _byteswap_ulong
#elif GCC_VERSION >= 403
# define XXH_swap32 __builtin_bswap32
#else
static inline U32 XXH_swap32 (U32 x) {
return ((x << 24) & 0xff000000 ) |
((x << 8) & 0x00ff0000 ) |
((x >> 8) & 0x0000ff00 ) |
((x >> 24) & 0x000000ff );}
#endif
//**************************************
// Constants
//**************************************
#define PRIME32_1 2654435761U
#define PRIME32_2 2246822519U
#define PRIME32_3 3266489917U
#define PRIME32_4 668265263U
#define PRIME32_5 374761393U
//**************************************
// Architecture Macros
//**************************************
typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
#ifndef XXH_CPU_LITTLE_ENDIAN // It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch
static const int one = 1;
# define XXH_CPU_LITTLE_ENDIAN (*(char*)(&one))
#endif
//**************************************
// Macros
//**************************************
#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } // use only *after* variable declarations
//****************************
// Memory reads
//****************************
typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
FORCE_INLINE U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align)
{
if (align==XXH_unaligned)
return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr));
else
return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr);
}
FORCE_INLINE U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); }
//****************************
// Simple Hash Functions
//****************************
FORCE_INLINE U32 XXH32_endian_align(const void* input, int len, U32 seed, XXH_endianess endian, XXH_alignment align)
{
const BYTE* p = (const BYTE*)input;
const BYTE* const bEnd = p + len;
U32 h32;
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
if (p==NULL) { len=0; p=(const BYTE*)(size_t)16; }
#endif
if (len>=16)
{
const BYTE* const limit = bEnd - 16;
U32 v1 = seed + PRIME32_1 + PRIME32_2;
U32 v2 = seed + PRIME32_2;
U32 v3 = seed + 0;
U32 v4 = seed - PRIME32_1;
do
{
v1 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
v2 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
v3 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
v4 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
} while (p<=limit);
h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
}
else
{
h32 = seed + PRIME32_5;
}
h32 += (U32) len;
while (p<=bEnd-4)
{
h32 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_3;
h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
p+=4;
}
while (p<bEnd)
{
h32 += (*p) * PRIME32_5;
h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
p++;
}
h32 ^= h32 >> 15;
h32 *= PRIME32_2;
h32 ^= h32 >> 13;
h32 *= PRIME32_3;
h32 ^= h32 >> 16;
return h32;
}
U32 XXH32(const void* input, int len, U32 seed)
{
#if 0
// Simple version, good for code maintenance, but unfortunately slow for small inputs
void* state = XXH32_init(seed);
XXH32_update(state, input, len);
return XXH32_digest(state);
#else
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
# if !defined(XXH_USE_UNALIGNED_ACCESS)
if ((((size_t)input) & 3)) // Input is aligned, let's leverage the speed advantage
{
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
else
return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
}
# endif
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
else
return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
#endif
}
//****************************
// Advanced Hash Functions
//****************************
struct XXH_state32_t
{
U64 total_len;
U32 seed;
U32 v1;
U32 v2;
U32 v3;
U32 v4;
int memsize;
char memory[16];
};
int XXH32_sizeofState()
{
XXH_STATIC_ASSERT(XXH32_SIZEOFSTATE >= sizeof(struct XXH_state32_t)); // A compilation error here means XXH32_SIZEOFSTATE is not large enough
return sizeof(struct XXH_state32_t);
}
XXH_errorcode XXH32_resetState(void* state_in, U32 seed)
{
struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
state->seed = seed;
state->v1 = seed + PRIME32_1 + PRIME32_2;
state->v2 = seed + PRIME32_2;
state->v3 = seed + 0;
state->v4 = seed - PRIME32_1;
state->total_len = 0;
state->memsize = 0;
return XXH_OK;
}
void* XXH32_init (U32 seed)
{
void* state = XXH_malloc (sizeof(struct XXH_state32_t));
XXH32_resetState(state, seed);
return state;
}
FORCE_INLINE XXH_errorcode XXH32_update_endian (void* state_in, const void* input, int len, XXH_endianess endian)
{
struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
const BYTE* p = (const BYTE*)input;
const BYTE* const bEnd = p + len;
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
if (input==NULL) return XXH_ERROR;
#endif
state->total_len += len;
if (state->memsize + len < 16) // fill in tmp buffer
{
XXH_memcpy(state->memory + state->memsize, input, len);
state->memsize += len;
return XXH_OK;
}
if (state->memsize) // some data left from previous update
{
XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize);
{
const U32* p32 = (const U32*)state->memory;
state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++;
state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++;
state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++;
state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++;
}
p += 16-state->memsize;
state->memsize = 0;
}
if (p <= bEnd-16)
{
const BYTE* const limit = bEnd - 16;
U32 v1 = state->v1;
U32 v2 = state->v2;
U32 v3 = state->v3;
U32 v4 = state->v4;
do
{
v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
} while (p<=limit);
state->v1 = v1;
state->v2 = v2;
state->v3 = v3;
state->v4 = v4;
}
if (p < bEnd)
{
XXH_memcpy(state->memory, p, bEnd-p);
state->memsize = (int)(bEnd-p);
}
return XXH_OK;
}
XXH_errorcode XXH32_update (void* state_in, const void* input, int len)
{
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
else
return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
}
FORCE_INLINE U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess endian)
{
struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
const BYTE * p = (const BYTE*)state->memory;
BYTE* bEnd = (BYTE*)state->memory + state->memsize;
U32 h32;
if (state->total_len >= 16)
{
h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
}
else
{
h32 = state->seed + PRIME32_5;
}
h32 += (U32) state->total_len;
while (p<=bEnd-4)
{
h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3;
h32 = XXH_rotl32(h32, 17) * PRIME32_4;
p+=4;
}
while (p<bEnd)
{
h32 += (*p) * PRIME32_5;
h32 = XXH_rotl32(h32, 11) * PRIME32_1;
p++;
}
h32 ^= h32 >> 15;
h32 *= PRIME32_2;
h32 ^= h32 >> 13;
h32 *= PRIME32_3;
h32 ^= h32 >> 16;
return h32;
}
U32 XXH32_intermediateDigest (void* state_in)
{
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
return XXH32_intermediateDigest_endian(state_in, XXH_littleEndian);
else
return XXH32_intermediateDigest_endian(state_in, XXH_bigEndian);
}
U32 XXH32_digest (void* state_in)
{
U32 h32 = XXH32_intermediateDigest(state_in);
XXH_free(state_in);
return h32;
}

164
lib/BasicsC/xxhash.h Normal file
View File

@ -0,0 +1,164 @@
/*
xxHash - Fast Hash algorithm
Header File
Copyright (C) 2012-2014, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at :
- xxHash source repository : http://code.google.com/p/xxhash/
*/
/* Notice extracted from xxHash homepage :
xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
It also successfully passes all tests from the SMHasher suite.
Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
Name Speed Q.Score Author
xxHash 5.4 GB/s 10
CrapWow 3.2 GB/s 2 Andrew
MumurHash 3a 2.7 GB/s 10 Austin Appleby
SpookyHash 2.0 GB/s 10 Bob Jenkins
SBox 1.4 GB/s 9 Bret Mulvey
Lookup3 1.2 GB/s 9 Bob Jenkins
SuperFastHash 1.2 GB/s 1 Paul Hsieh
CityHash64 1.05 GB/s 10 Pike & Alakuijala
FNV 0.55 GB/s 5 Fowler, Noll, Vo
CRC32 0.43 GB/s 9
MD5-32 0.33 GB/s 10 Ronald L. Rivest
SHA1-32 0.28 GB/s 10
Q.Score is a measure of quality of the hash function.
It depends on successfully passing SMHasher test set.
10 is a perfect score.
*/
#pragma once
#if defined (__cplusplus)
extern "C" {
#endif
//****************************
// Type
//****************************
typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
//****************************
// Simple Hash Functions
//****************************
unsigned int XXH32 (const void* input, int len, unsigned int seed);
/*
XXH32() :
Calculate the 32-bits hash of sequence of length "len" stored at memory address "input".
The memory between input & input+len must be valid (allocated and read-accessible).
"seed" can be used to alter the result predictably.
This function successfully passes all SMHasher tests.
Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
Note that "len" is type "int", which means it is limited to 2^31-1.
If your data is larger, use the advanced functions below.
*/
//****************************
// Advanced Hash Functions
//****************************
void* XXH32_init (unsigned int seed);
XXH_errorcode XXH32_update (void* state, const void* input, int len);
unsigned int XXH32_digest (void* state);
/*
These functions calculate the xxhash of an input provided in several small packets,
as opposed to an input provided as a single block.
It must be started with :
void* XXH32_init()
The function returns a pointer which holds the state of calculation.
This pointer must be provided as "void* state" parameter for XXH32_update().
XXH32_update() can be called as many times as necessary.
The user must provide a valid (allocated) input.
The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
Note that "len" is type "int", which means it is limited to 2^31-1.
If your data is larger, it is recommended to chunk your data into blocks
of size for example 2^30 (1GB) to avoid any "int" overflow issue.
Finally, you can end the calculation anytime, by using XXH32_digest().
This function returns the final 32-bits hash.
You must provide the same "void* state" parameter created by XXH32_init().
Memory will be freed by XXH32_digest().
*/
int XXH32_sizeofState(void);
XXH_errorcode XXH32_resetState(void* state, unsigned int seed);
#define XXH32_SIZEOFSTATE 48
typedef struct { long long ll[(XXH32_SIZEOFSTATE+(sizeof(long long)-1))/sizeof(long long)]; } XXH32_stateSpace_t;
/*
These functions allow user application to make its own allocation for state.
XXH32_sizeofState() is used to know how much space must be allocated for the xxHash 32-bits state.
Note that the state must be aligned to access 'long long' fields. Memory must be allocated and referenced by a pointer.
This pointer must then be provided as 'state' into XXH32_resetState(), which initializes the state.
For static allocation purposes (such as allocation on stack, or freestanding systems without malloc()),
use the structure XXH32_stateSpace_t, which will ensure that memory space is large enough and correctly aligned to access 'long long' fields.
*/
unsigned int XXH32_intermediateDigest (void* state);
/*
This function does the same as XXH32_digest(), generating a 32-bit hash,
but preserve memory context.
This way, it becomes possible to generate intermediate hashes, and then continue feeding data with XXH32_update().
To free memory context, use XXH32_digest(), or free().
*/
//****************************
// Deprecated function names
//****************************
// The following translations are provided to ease code transition
// You are encouraged to no longer this function names
#define XXH32_feed XXH32_update
#define XXH32_result XXH32_digest
#define XXH32_getIntermediateResult XXH32_intermediateDigest
#if defined (__cplusplus)
}
#endif

View File

@ -42,6 +42,7 @@ lib_libarango_a_SOURCES = \
lib/BasicsC/csv.c \
lib/BasicsC/debugging.c \
lib/BasicsC/error.c \
lib/BasicsC/fasthash.c \
lib/BasicsC/files.c \
lib/BasicsC/hashes.c \
lib/BasicsC/init.c \
@ -71,6 +72,7 @@ lib_libarango_a_SOURCES = \
lib/BasicsC/vector.c \
lib/BasicsC/voc-errors.c \
lib/BasicsC/voc-mimetypes.c \
lib/BasicsC/xxhash.c \
lib/BasicsC/tri-zip.c \
lib/JsonParser/json-parser.c \
lib/ProgramOptions/program-options.c \