mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel
This commit is contained in:
commit
b0fc77d83d
|
@ -1,6 +1,12 @@
|
||||||
v1.3 (XXXX-XX-XX)
|
v1.3 (XXXX-XX-XX)
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
* added server startup flag `--database.force-sync-properties` to force syncing of
|
||||||
|
collection properties on collection creation, deletion and on property update.
|
||||||
|
The default value is true to mimic the behavior of previous versions of ArangoDB.
|
||||||
|
If set to false, collection properties are written to disk but no call to sync()
|
||||||
|
is made.
|
||||||
|
|
||||||
* added detailed output of server version and components for REST APIs
|
* added detailed output of server version and components for REST APIs
|
||||||
`/_admin/version` and `/_api/version`. To retrieve this extended information,
|
`/_admin/version` and `/_api/version`. To retrieve this extended information,
|
||||||
call the REST APIs with URL parameter `details=true`.
|
call the REST APIs with URL parameter `details=true`.
|
||||||
|
|
|
@ -143,6 +143,10 @@ the option `--disable-figures`.
|
||||||
@anchor CommandLineArangoWaitForSync
|
@anchor CommandLineArangoWaitForSync
|
||||||
@copydetails triagens::arango::ArangoServer::_defaultWaitForSync
|
@copydetails triagens::arango::ArangoServer::_defaultWaitForSync
|
||||||
|
|
||||||
|
@CLEARPAGE
|
||||||
|
@anchor CommandLineArangoForceSyncProperties
|
||||||
|
@copydetails triagens::arango::ArangoServer::_forceSyncProperties
|
||||||
|
|
||||||
@CLEARPAGE
|
@CLEARPAGE
|
||||||
@anchor CommandLineArangoForceSyncShapes
|
@anchor CommandLineArangoForceSyncShapes
|
||||||
@copydetails triagens::arango::ArangoServer::_forceSyncShapes
|
@copydetails triagens::arango::ArangoServer::_forceSyncShapes
|
||||||
|
|
|
@ -28,6 +28,7 @@ TOC {#CommandLineTOC}
|
||||||
- @ref CommandLineArangoDirectory "database.directory"
|
- @ref CommandLineArangoDirectory "database.directory"
|
||||||
- @ref CommandLineArangoMaximalJournalSize "database.maximal-journal-size"
|
- @ref CommandLineArangoMaximalJournalSize "database.maximal-journal-size"
|
||||||
- @ref CommandLineArangoWaitForSync "database.wait-for-sync"
|
- @ref CommandLineArangoWaitForSync "database.wait-for-sync"
|
||||||
|
- @ref CommandLineArangoForceSyncProperties "database.force-sync-properties"
|
||||||
- @ref CommandLineArangoForceSyncShapes "database.force-sync-shapes"
|
- @ref CommandLineArangoForceSyncShapes "database.force-sync-shapes"
|
||||||
- @ref CommandLineArangoRemoveOnDrop "database.remove-on-compacted"
|
- @ref CommandLineArangoRemoveOnDrop "database.remove-on-compacted"
|
||||||
- @ref CommandLineArangoJsGcFrequency "javascript.gc-frequency"
|
- @ref CommandLineArangoJsGcFrequency "javascript.gc-frequency"
|
||||||
|
|
|
@ -77,6 +77,7 @@ SERVER_OPT := \
|
||||||
--configuration none \
|
--configuration none \
|
||||||
--database.maximal-journal-size 1048576 \
|
--database.maximal-journal-size 1048576 \
|
||||||
--database.force-sync-shapes false \
|
--database.force-sync-shapes false \
|
||||||
|
--database.force-sync-properties false \
|
||||||
--javascript.action-directory @top_srcdir@/js/actions/system \
|
--javascript.action-directory @top_srcdir@/js/actions/system \
|
||||||
--javascript.gc-interval 1 \
|
--javascript.gc-interval 1 \
|
||||||
--javascript.modules-path @top_srcdir@/js/server/modules:@top_srcdir@/js/common/modules \
|
--javascript.modules-path @top_srcdir@/js/server/modules:@top_srcdir@/js/common/modules \
|
||||||
|
|
|
@ -410,8 +410,9 @@ char* TRI_RegisterStringAql (TRI_aql_context_t* const context,
|
||||||
ABORT_OOM
|
ABORT_OOM
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deescape) {
|
if (deescape && length > 0) {
|
||||||
size_t outLength;
|
size_t outLength;
|
||||||
|
|
||||||
copy = TRI_UnescapeUtf8StringZ(TRI_UNKNOWN_MEM_ZONE, value, length, &outLength);
|
copy = TRI_UnescapeUtf8StringZ(TRI_UNKNOWN_MEM_ZONE, value, length, &outLength);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -92,7 +92,9 @@ static int AllocateSubObjectsHashIndexElement (TRI_hash_index_t const* idx,
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void FreeSubObjectsHashIndexElement (TRI_hash_index_element_t* element) {
|
static void FreeSubObjectsHashIndexElement (TRI_hash_index_element_t* element) {
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, element->_subObjects);
|
if (element->_subObjects != NULL) {
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, element->_subObjects);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -248,7 +250,9 @@ static int HashIndex_insert (TRI_hash_index_t* hashIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
res = TRI_InsertKeyHashArray(&hashIndex->_hashArray, &key, element, false);
|
res = TRI_InsertKeyHashArray(&hashIndex->_hashArray, &key, element, false);
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, key._values);
|
if (key._values != NULL) {
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, key._values);
|
||||||
|
}
|
||||||
|
|
||||||
if (res == TRI_RESULT_KEY_EXISTS) {
|
if (res == TRI_RESULT_KEY_EXISTS) {
|
||||||
return TRI_set_errno(TRI_ERROR_ARANGO_UNIQUE_CONSTRAINT_VIOLATED);
|
return TRI_set_errno(TRI_ERROR_ARANGO_UNIQUE_CONSTRAINT_VIOLATED);
|
||||||
|
|
|
@ -71,6 +71,8 @@ bin_arangod_SOURCES = \
|
||||||
arangod/RestServer/arango.cpp \
|
arangod/RestServer/arango.cpp \
|
||||||
arangod/SkipLists/skiplist.c \
|
arangod/SkipLists/skiplist.c \
|
||||||
arangod/SkipLists/skiplistIndex.c \
|
arangod/SkipLists/skiplistIndex.c \
|
||||||
|
arangod/SkipListsEx/skiplistEx.c \
|
||||||
|
arangod/SkipListsEx/skiplistExIndex.c \
|
||||||
arangod/V8Server/ApplicationV8.cpp \
|
arangod/V8Server/ApplicationV8.cpp \
|
||||||
arangod/V8Server/v8-actions.cpp \
|
arangod/V8Server/v8-actions.cpp \
|
||||||
arangod/V8Server/v8-query.cpp \
|
arangod/V8Server/v8-query.cpp \
|
||||||
|
|
|
@ -181,6 +181,7 @@ ArangoServer::ArangoServer (int argc, char** argv)
|
||||||
_defaultMaximalSize(TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE),
|
_defaultMaximalSize(TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE),
|
||||||
_defaultWaitForSync(false),
|
_defaultWaitForSync(false),
|
||||||
_forceSyncShapes(true),
|
_forceSyncShapes(true),
|
||||||
|
_forceSyncProperties(true),
|
||||||
_vocbase(0) {
|
_vocbase(0) {
|
||||||
|
|
||||||
// locate path to binary
|
// locate path to binary
|
||||||
|
@ -334,6 +335,7 @@ void ArangoServer::buildApplicationServer () {
|
||||||
("database.maximal-journal-size", &_defaultMaximalSize, "default maximal journal size, can be overwritten when creating a collection")
|
("database.maximal-journal-size", &_defaultMaximalSize, "default maximal journal size, can be overwritten when creating a collection")
|
||||||
("database.wait-for-sync", &_defaultWaitForSync, "default wait-for-sync behavior, can be overwritten when creating a collection")
|
("database.wait-for-sync", &_defaultWaitForSync, "default wait-for-sync behavior, can be overwritten when creating a collection")
|
||||||
("database.force-sync-shapes", &_forceSyncShapes, "force syncing of shape data to disk, will use waitForSync value of collection when turned off")
|
("database.force-sync-shapes", &_forceSyncShapes, "force syncing of shape data to disk, will use waitForSync value of collection when turned off")
|
||||||
|
("database.force-sync-properties", &_forceSyncProperties, "force syncing of collection properties to disk, will use waitForSync value of collection when turned off")
|
||||||
;
|
;
|
||||||
|
|
||||||
additional["DATABASE Options:help-devel"]
|
additional["DATABASE Options:help-devel"]
|
||||||
|
@ -1074,6 +1076,7 @@ void ArangoServer::openDatabase () {
|
||||||
_vocbase->_defaultMaximalSize = _defaultMaximalSize;
|
_vocbase->_defaultMaximalSize = _defaultMaximalSize;
|
||||||
_vocbase->_defaultWaitForSync = _defaultWaitForSync;
|
_vocbase->_defaultWaitForSync = _defaultWaitForSync;
|
||||||
_vocbase->_forceSyncShapes = _forceSyncShapes;
|
_vocbase->_forceSyncShapes = _forceSyncShapes;
|
||||||
|
_vocbase->_forceSyncProperties = _forceSyncProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -347,20 +347,37 @@ namespace triagens {
|
||||||
bool _defaultWaitForSync;
|
bool _defaultWaitForSync;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief force sync shapes
|
/// @brief force syncing of shape data
|
||||||
///
|
///
|
||||||
/// @CMDOPT{\--database.force-sync-shapes @CA{boolean}}
|
/// @CMDOPT{\--database.force-sync-shapes @CA{boolean}}
|
||||||
///
|
///
|
||||||
/// Force syncing of shape data to disk when writing shape information.
|
/// Force syncing of shape data to disk when writing shape information.
|
||||||
/// If turned off, syncing will still happen for shapes of collections that
|
/// If turned off, syncing will still happen for shapes of collections that
|
||||||
/// have a waitForSync value of @LIT{true}. If turned on, syncing of shape data
|
/// have a waitForSync value of @LIT{true}. If turned on, syncing of shape data
|
||||||
/// will always happen, regards of the value of waitForSync.
|
/// will always happen, regardless of the value of waitForSync.
|
||||||
///
|
///
|
||||||
/// The default is @LIT{true}.
|
/// The default is @LIT{true}.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool _forceSyncShapes;
|
bool _forceSyncShapes;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief force syncing of collection properties
|
||||||
|
///
|
||||||
|
/// @CMDOPT{\--database.force-sync-properties @CA{boolean}}
|
||||||
|
///
|
||||||
|
/// Force syncing of collection properties to disk after creating a collection
|
||||||
|
/// or updating its properties.
|
||||||
|
///
|
||||||
|
/// If turned off, syncing will still happen for collection that have a
|
||||||
|
/// waitForSync value of @LIT{true}. If turned on, syncing of properties will
|
||||||
|
/// always happen, regardless of the value of waitForSync.
|
||||||
|
///
|
||||||
|
/// The default is @LIT{true}.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool _forceSyncProperties;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief unit tests
|
/// @brief unit tests
|
||||||
///
|
///
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,557 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief skip list which suports transactions implementation
|
||||||
|
///
|
||||||
|
/// @file
|
||||||
|
///
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2004-2012 triagens GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// @author Dr. O
|
||||||
|
/// @author Copyright 2006-2012, triAGENS GmbH, Cologne, Germany
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TRIAGENS_BASICS_C_SKIPLIST_EX_H
|
||||||
|
#define TRIAGENS_BASICS_C_SKIPLIST_EX_H 1
|
||||||
|
|
||||||
|
#include "BasicsC/common.h"
|
||||||
|
#include "BasicsC/locks.h"
|
||||||
|
#include "BasicsC/vector.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- skiplistEx public types
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup SkiplistEx
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief types which enumerate the probability used to determine the height of node
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TRI_SKIPLIST_EX_PROB_HALF,
|
||||||
|
TRI_SKIPLIST_EX_PROB_THIRD,
|
||||||
|
TRI_SKIPLIST_EX_PROB_QUARTER
|
||||||
|
}
|
||||||
|
TRI_skiplistEx_prob_e;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TRI_SKIPLIST_EX_COMPARE_STRICTLY_LESS = -1,
|
||||||
|
TRI_SKIPLIST_EX_COMPARE_STRICTLY_GREATER = 1,
|
||||||
|
TRI_SKIPLIST_EX_COMPARE_STRICTLY_EQUAL = 0,
|
||||||
|
TRI_SKIPLIST_EX_COMPARE_SLIGHTLY_LESS = -2,
|
||||||
|
TRI_SKIPLIST_EX_COMPARE_SLIGHTLY_GREATER = 2
|
||||||
|
}
|
||||||
|
TRI_skiplistEx_compare_e;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief storage structure for a node's nearest neighbours
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// .............................................................................
|
||||||
|
// The nearest neighbour node needs to be modified for handling transactions.
|
||||||
|
// We introduce a structure for the forward and back links.
|
||||||
|
// To implement 'lock free', we require an atomic Compare & Save (C&S) function
|
||||||
|
// to use this correctly on Mac/Windows we need to align pointer/integers
|
||||||
|
// on 32 or 64 bit boundaries.
|
||||||
|
// .............................................................................
|
||||||
|
|
||||||
|
typedef struct TRI_skiplistEx_nb_s {
|
||||||
|
void* _prev; // points to the previous nearest neighbour of this node (the left node)
|
||||||
|
void* _next; // points to the successor of this node (right node)
|
||||||
|
uint64_t _flag; // the _flag field operates as follows:
|
||||||
|
// if (_flag & 1) == 1, then the Tower Node (the node which uses this structure) is a Glass Tower Node.
|
||||||
|
//
|
||||||
|
} TRI_skiplistEx_nb_t; // nearest neighbour;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief structure of a skip list node (unique and non-unique)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct TRI_skiplistEx_node_s {
|
||||||
|
TRI_skiplistEx_nb_t* _column; // these represent the levels and the links within these, an array of these
|
||||||
|
uint32_t _colLength; // the height of the column
|
||||||
|
void* _extraData;
|
||||||
|
void* _element;
|
||||||
|
uint64_t _delTransID; // the transaction id which removed (deleted) this node
|
||||||
|
uint64_t _insTransID; // the transaction id which inserted this node
|
||||||
|
}
|
||||||
|
TRI_skiplistEx_node_t;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief The base structure of a skiplist (unique and non-unique)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct TRI_skiplistEx_base_s {
|
||||||
|
// ...........................................................................
|
||||||
|
// The maximum height of this skip list. Thus 2^(_maxHeight) elements can be
|
||||||
|
// stored in the skip list.
|
||||||
|
// ...........................................................................
|
||||||
|
uint32_t _maxHeight;
|
||||||
|
|
||||||
|
// ...........................................................................
|
||||||
|
// The size of each element which is to be stored.
|
||||||
|
// ...........................................................................
|
||||||
|
uint32_t _elementSize;
|
||||||
|
|
||||||
|
// ...........................................................................
|
||||||
|
// The actual list itself
|
||||||
|
// ...........................................................................
|
||||||
|
char* _skiplist;
|
||||||
|
|
||||||
|
// ...........................................................................
|
||||||
|
// The probability which is used to determine the level for insertions
|
||||||
|
// into the list. Note the following
|
||||||
|
// ...........................................................................
|
||||||
|
TRI_skiplistEx_prob_e _prob;
|
||||||
|
int32_t _numRandom;
|
||||||
|
uint32_t* _random;
|
||||||
|
|
||||||
|
|
||||||
|
TRI_skiplistEx_node_t _startNode;
|
||||||
|
TRI_skiplistEx_node_t _endNode;
|
||||||
|
|
||||||
|
}
|
||||||
|
TRI_skiplistEx_base_t;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- unique skiplistEx public types
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup SkiplistEx_unique
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief structure used for a skip list which only accepts unique entries
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct TRI_skiplistEx_s {
|
||||||
|
TRI_skiplistEx_base_t _base;
|
||||||
|
// ...........................................................................
|
||||||
|
// callback compare function
|
||||||
|
// < 0: implies left < right
|
||||||
|
// == 0: implies left == right
|
||||||
|
// > 0: implies left > right
|
||||||
|
// ...........................................................................
|
||||||
|
int (*compareElementElement) (struct TRI_skiplistEx_s*, void*, void*, int);
|
||||||
|
int (*compareKeyElement) (struct TRI_skiplistEx_s*, void*, void*, int);
|
||||||
|
}
|
||||||
|
TRI_skiplistEx_t;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief structure used for a skip list which only accepts unique entries and is thread safe
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// structure for a skiplist which allows unique entries -- with locking
|
||||||
|
// available for its nearest neighbours.
|
||||||
|
// TODO: implement locking for nearest neighbours rather than for all of index
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct TRI_skiplistEx_synced_s {
|
||||||
|
TRI_skiplistEx_t _base;
|
||||||
|
TRI_read_write_lock_t _lock;
|
||||||
|
} TRI_skiplistEx_synced_t;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- unique skiplist constructors and destructors
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup Skiplist_unique
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief initialises a skip list
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int TRI_InitSkipListEx (TRI_skiplistEx_t*,
|
||||||
|
size_t elementSize,
|
||||||
|
int (*compareElementElement) (TRI_skiplistEx_t*, void*, void*, int),
|
||||||
|
int (*compareKeyElement) (TRI_skiplistEx_t*, void*, void*, int),
|
||||||
|
TRI_skiplistEx_prob_e,
|
||||||
|
uint32_t,
|
||||||
|
uint64_t lastKnownTransID);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief destroys a skip list, but does not free the pointer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_DestroySkipListEx (TRI_skiplistEx_t*);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief destroys a skip list and frees the pointer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_FreeSkipListEx (TRI_skiplistEx_t*);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- unique skiplist public functions
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup Skiplist_unique
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns the end node which belongs to a skiplist
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_EndNodeSkipListEx (TRI_skiplistEx_t*);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief adds an element to the skip list using element for comparison
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int TRI_InsertElementSkipListEx (TRI_skiplistEx_t*, void*, bool, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief adds an element to the skip list using key for comparison
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int TRI_InsertKeySkipListEx (TRI_skiplistEx_t*, void*, void*, bool, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief lookups an element given a key, returns greatest left element
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_LeftLookupByKeySkipListEx (TRI_skiplistEx_t*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief lookups an element given a key, returns null if not found
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_LookupByKeySkipListEx (TRI_skiplistEx_t*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief given a node returns the next node in the skip list, if the end is reached returns the end node
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_NextNodeSkipListEx (TRI_skiplistEx_t*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief given a node returns the prev node in the skip list, if the beginning is reached returns the start node
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_PrevNodeSkipListEx (TRI_skiplistEx_t*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief removes an element from the skip list using element for comparison
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int TRI_RemoveElementSkipListEx (TRI_skiplistEx_t*, void*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief removes an element from the skip list using key for comparison
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int TRI_RemoveKeySkipListEx (TRI_skiplistEx_t*, void*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief lookups an element given a key, returns least right element
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_RightLookupByKeySkipListEx (TRI_skiplistEx_t*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns the start node which belongs to a skiplist
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_StartNodeSkipListEx (TRI_skiplistEx_t*);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- non-unique skiplist public types
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief structure used for a multi skiplist
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup Skiplist_non_unique
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct TRI_skiplistEx_multi_s {
|
||||||
|
TRI_skiplistEx_base_t _base;
|
||||||
|
// ...........................................................................
|
||||||
|
// callback compare function
|
||||||
|
// < 0: implies left < right
|
||||||
|
// == 0: implies left == right
|
||||||
|
// > 0: implies left > right
|
||||||
|
// ...........................................................................
|
||||||
|
int (*compareElementElement) (struct TRI_skiplistEx_multi_s*, void*, void*, int);
|
||||||
|
int (*compareKeyElement) (struct TRI_skiplistEx_multi_s*, void*, void*, int);
|
||||||
|
|
||||||
|
// ...........................................................................
|
||||||
|
// Returns true if the element is an exact copy, or if the data which the
|
||||||
|
// element points to is an exact copy
|
||||||
|
// ...........................................................................
|
||||||
|
bool (*equalElementElement) (struct TRI_skiplistEx_multi_s*, void*, void*);
|
||||||
|
} TRI_skiplistEx_multi_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief structure used for a multi skip list and is thread safe
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct TRI_skiplistEx_synced_multi_s {
|
||||||
|
TRI_skiplistEx_t _base;
|
||||||
|
TRI_read_write_lock_t _lock;
|
||||||
|
} TRI_skiplistEx_synced_multi_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- non-unique skiplist constructors and destructors
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup Skiplist_non_unique
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief initialises a skip list
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
int TRI_InitSkipListExMulti (TRI_skiplistEx_multi_t*,
|
||||||
|
size_t elementSize,
|
||||||
|
int (*compareElementElement) (TRI_skiplistEx_multi_t*, void*, void*, int),
|
||||||
|
int (*compareKeyElement) (TRI_skiplistEx_multi_t*, void*, void*, int),
|
||||||
|
bool (*equalElementElement) (TRI_skiplistEx_multi_t*, void*, void*),
|
||||||
|
TRI_skiplistEx_prob_e,
|
||||||
|
uint32_t,
|
||||||
|
uint64_t lastKnownTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief destroys a multi skip list, but does not free the pointer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_DestroySkipListExMulti (TRI_skiplistEx_multi_t*);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief destroys a skip list and frees the pointer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_FreeSkipListExMulti (TRI_skiplistEx_multi_t*);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- non-unique skiplistEx public functions
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup SkiplistEx_non_unique
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns the end node which belongs to a skiplist
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_EndNodeSkipListExMulti (TRI_skiplistEx_multi_t*);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief adds an element to the skip list using element for comparison
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int TRI_InsertElementSkipListExMulti (TRI_skiplistEx_multi_t*, void*, bool, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief adds an element to the skip list using key for comparison
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int TRI_InsertKeySkipListExMulti (TRI_skiplistEx_multi_t*, void*, void*, bool, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief lookups an element given a key, returns greatest left element
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_LeftLookupByKeySkipListExMulti (TRI_skiplistEx_multi_t*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief lookups an element given a key, returns null if not found
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_LookupByKeySkipListExMulti (TRI_skiplistEx_multi_t*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief given a node returns the next node in the skip list, if the end is reached returns the end node
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_NextNodeSkipListExMulti (TRI_skiplistEx_multi_t*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief given a node returns the prev node in the skip list, if the beginning is reached returns the start node
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_PrevNodeSkipListExMulti (TRI_skiplistEx_multi_t*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief removes an element from the skip list using element for comparison
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int TRI_RemoveElementSkipListExMulti (TRI_skiplistEx_multi_t*, void*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief removes an element from the skip list using key for comparison
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int TRI_RemoveKeySkipListExMulti (TRI_skiplistEx_multi_t*, void*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief lookups an element given a key, returns least right element
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_RightLookupByKeySkipListExMulti (TRI_skiplistEx_multi_t*, void*, uint64_t thisTransID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns the start node which belongs to a skiplist
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* TRI_StartNodeSkipListExMulti (TRI_skiplistEx_multi_t*);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Local Variables:
|
||||||
|
// mode: outline-minor
|
||||||
|
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
||||||
|
// End:
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,208 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief unique and non-unique skip lists which support transactions
|
||||||
|
///
|
||||||
|
/// @file
|
||||||
|
///
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright by triAGENS GmbH - All rights reserved.
|
||||||
|
///
|
||||||
|
/// The Programs (which include both the software and documentation)
|
||||||
|
/// contain proprietary information of triAGENS GmbH; they are
|
||||||
|
/// provided under a license agreement containing restrictions on use and
|
||||||
|
/// disclosure and are also protected by copyright, patent and other
|
||||||
|
/// intellectual and industrial property laws. Reverse engineering,
|
||||||
|
/// disassembly or decompilation of the Programs, except to the extent
|
||||||
|
/// required to obtain interoperability with other independently created
|
||||||
|
/// software or as specified by law, is prohibited.
|
||||||
|
///
|
||||||
|
/// The Programs are not intended for use in any nuclear, aviation, mass
|
||||||
|
/// transit, medical, or other inherently dangerous applications. It shall
|
||||||
|
/// be the licensee's responsibility to take all appropriate fail-safe,
|
||||||
|
/// backup, redundancy, and other measures to ensure the safe use of such
|
||||||
|
/// applications if the Programs are used for such purposes, and triAGENS
|
||||||
|
/// GmbH disclaims liability for any damages caused by such use of
|
||||||
|
/// the Programs.
|
||||||
|
///
|
||||||
|
/// This software is the confidential and proprietary information of
|
||||||
|
/// triAGENS GmbH. You shall not disclose such confidential and
|
||||||
|
/// proprietary information and shall use it only in accordance with the
|
||||||
|
/// terms of the license agreement you entered into with triAGENS GmbH.
|
||||||
|
///
|
||||||
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// @author Dr. O
|
||||||
|
/// @author Copyright 2011, triagens GmbH, Cologne, Germany
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef TRIAGENS_DURHAM_VOC_BASE_SKIPLIST_EX_INDEX_H
|
||||||
|
#define TRIAGENS_DURHAM_VOC_BASE_SKIPLIST_EX_INDEX_H 1
|
||||||
|
|
||||||
|
#include <BasicsC/common.h>
|
||||||
|
#include "SkipListsEx/skiplistEx.h"
|
||||||
|
#include "IndexIterators/index-iterator.h"
|
||||||
|
#include "IndexOperators/index-operator.h"
|
||||||
|
#include "ShapedJson/shaped-json.h"
|
||||||
|
#include "VocBase/transaction.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- skiplistExIndex public types
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup skiplistExIndex
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
TRI_skiplistEx_t* uniqueSkiplistEx;
|
||||||
|
TRI_skiplistEx_multi_t* nonUniqueSkiplistEx;
|
||||||
|
} _skiplistEx;
|
||||||
|
bool _unique;
|
||||||
|
TRI_transaction_context_t* _transactionContext;
|
||||||
|
} SkiplistExIndex;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t numFields; // the number of fields
|
||||||
|
TRI_shaped_json_t* fields; // list of shaped json objects which the collection should know about
|
||||||
|
void* data; // master document pointer
|
||||||
|
void* collection; // pointer to the collection;
|
||||||
|
} SkiplistExIndexElement;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t _numElements;
|
||||||
|
SkiplistExIndexElement* _elements; // simple list of elements
|
||||||
|
} SkiplistExIndexElements;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Iterator structure for skip list. We require a start and stop node
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct TRI_skiplistEx_iterator_interval_s {
|
||||||
|
void* _leftEndPoint;
|
||||||
|
void* _rightEndPoint;
|
||||||
|
} TRI_skiplistEx_iterator_interval_t;
|
||||||
|
|
||||||
|
// ............................................................................
|
||||||
|
// The iterator essentially is reading a sequence of documents (which are
|
||||||
|
// stored in a corresponding sequence of nodes), we require the transaction
|
||||||
|
// number to which this iterator belongs to, this will ensure that any
|
||||||
|
// modifications made after this transaction are not 'iterated over'
|
||||||
|
// ............................................................................
|
||||||
|
|
||||||
|
typedef struct TRI_skiplistEx_iterator_s {
|
||||||
|
SkiplistExIndex* _index;
|
||||||
|
TRI_vector_t _intervals;
|
||||||
|
size_t _currentInterval; // starts with 0
|
||||||
|
void* _cursor; // initially null
|
||||||
|
uint64_t _thisTransID; // the transaction id to which this iterator belongs to
|
||||||
|
bool (*_hasNext) (struct TRI_skiplistEx_iterator_s*);
|
||||||
|
void* (*_next) (struct TRI_skiplistEx_iterator_s*);
|
||||||
|
void* (*_nexts) (struct TRI_skiplistEx_iterator_s*, int64_t jumpSize);
|
||||||
|
bool (*_hasPrev) (struct TRI_skiplistEx_iterator_s*);
|
||||||
|
void* (*_prev) (struct TRI_skiplistEx_iterator_s*);
|
||||||
|
void* (*_prevs) (struct TRI_skiplistEx_iterator_s*, int64_t jumpSize);
|
||||||
|
} TRI_skiplistEx_iterator_t;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- skiplistExIndex public methods
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup skiplistExIndex
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Free a skiplistEx iterator
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_FreeSkiplistExIterator (TRI_skiplistEx_iterator_t* const);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief destroys a skip list index , but does not free the pointer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void SkiplistExIndex_destroy (SkiplistExIndex*);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief destroys a skip list index and frees the pointer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void SkiplistExIndex_free (SkiplistExIndex*);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int SkiplistExIndex_assignMethod (void*, TRI_index_method_assignment_type_e);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Unique skiplist indexes
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
SkiplistExIndex* SkiplistExIndex_new (TRI_transaction_context_t*);
|
||||||
|
|
||||||
|
int SkiplistExIndex_add (SkiplistExIndex*, SkiplistExIndexElement*, uint64_t);
|
||||||
|
|
||||||
|
TRI_skiplistEx_iterator_t* SkiplistExIndex_find (SkiplistExIndex*, TRI_vector_t*, TRI_index_operator_t*, uint64_t);
|
||||||
|
|
||||||
|
int SkiplistExIndex_insert (SkiplistExIndex*, SkiplistExIndexElement*, uint64_t);
|
||||||
|
|
||||||
|
int SkiplistExIndex_remove (SkiplistExIndex*, SkiplistExIndexElement*, uint64_t);
|
||||||
|
|
||||||
|
bool SkiplistExIndex_update (SkiplistExIndex*, const SkiplistExIndexElement*, const SkiplistExIndexElement*, uint64_t);
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Multi-skiplist non-unique skiplist indexes
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
SkiplistExIndex* MultiSkiplistExIndex_new (TRI_transaction_context_t*);
|
||||||
|
|
||||||
|
int MultiSkiplistExIndex_add (SkiplistExIndex*, SkiplistExIndexElement*, uint64_t);
|
||||||
|
|
||||||
|
TRI_skiplistEx_iterator_t* MultiSkiplistExIndex_find (SkiplistExIndex*, TRI_vector_t*, TRI_index_operator_t*, uint64_t);
|
||||||
|
|
||||||
|
int MultiSkiplistExIndex_insert (SkiplistExIndex*, SkiplistExIndexElement*, uint64_t);
|
||||||
|
|
||||||
|
int MultiSkiplistExIndex_remove (SkiplistExIndex*, SkiplistExIndexElement*, uint64_t);
|
||||||
|
|
||||||
|
bool MultiSkiplistExIndex_update (SkiplistExIndex*, SkiplistExIndexElement*, SkiplistExIndexElement*, uint64_t);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Local Variables:
|
||||||
|
// mode: outline-minor
|
||||||
|
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
||||||
|
// End:
|
||||||
|
|
|
@ -3911,7 +3911,7 @@ static v8::Handle<v8::Value> EnsureBitarray (v8::Arguments const& argv, bool sup
|
||||||
|
|
||||||
ReleaseCollection(collection);
|
ReleaseCollection(collection);
|
||||||
|
|
||||||
if (!ok || bitarrayIndex == 0) {
|
if (! ok || bitarrayIndex == 0) {
|
||||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(errorCode, errorString)));
|
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(errorCode, errorString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5122,7 +5122,7 @@ static v8::Handle<v8::Value> JS_SetAttributeVocbaseCol (v8::Arguments const& arg
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == TRI_ERROR_NO_ERROR) {
|
if (res == TRI_ERROR_NO_ERROR) {
|
||||||
res = TRI_SaveCollectionInfo(collection->_path, &info);
|
res = TRI_SaveCollectionInfo(collection->_path, &info, collection->_vocbase->_forceSyncProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -969,7 +969,9 @@ int TRI_LoadCollectionInfo (char const* path,
|
||||||
/// function.
|
/// function.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int TRI_SaveCollectionInfo (char const* path, const TRI_col_info_t* const info) {
|
int TRI_SaveCollectionInfo (char const* path,
|
||||||
|
const TRI_col_info_t* const info,
|
||||||
|
const bool forceSync) {
|
||||||
TRI_json_t* json;
|
TRI_json_t* json;
|
||||||
char* filename;
|
char* filename;
|
||||||
bool ok;
|
bool ok;
|
||||||
|
@ -993,7 +995,7 @@ int TRI_SaveCollectionInfo (char const* path, const TRI_col_info_t* const info)
|
||||||
}
|
}
|
||||||
|
|
||||||
// save json info to file
|
// save json info to file
|
||||||
ok = TRI_SaveJson(filename, json);
|
ok = TRI_SaveJson(filename, json, forceSync);
|
||||||
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
||||||
|
|
||||||
if (! ok) {
|
if (! ok) {
|
||||||
|
@ -1055,7 +1057,7 @@ int TRI_UpdateCollectionInfo (TRI_vocbase_t* vocbase,
|
||||||
TRI_UNLOCK_JOURNAL_ENTRIES_DOC_COLLECTION((TRI_document_collection_t*) collection);
|
TRI_UNLOCK_JOURNAL_ENTRIES_DOC_COLLECTION((TRI_document_collection_t*) collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRI_SaveCollectionInfo(collection->_directory, &collection->_info);
|
return TRI_SaveCollectionInfo(collection->_directory, &collection->_info, vocbase->_forceSyncProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1072,7 +1074,7 @@ int TRI_RenameCollection (TRI_collection_t* collection, char const* name) {
|
||||||
TRI_CopyCollectionInfo(&new, &collection->_info);
|
TRI_CopyCollectionInfo(&new, &collection->_info);
|
||||||
TRI_CopyString(new._name, name, sizeof(new._name));
|
TRI_CopyString(new._name, name, sizeof(new._name));
|
||||||
|
|
||||||
res = TRI_SaveCollectionInfo(collection->_directory, &new);
|
res = TRI_SaveCollectionInfo(collection->_directory, &new, collection->_vocbase->_forceSyncProperties);
|
||||||
|
|
||||||
TRI_FreeCollectionInfoOptions(&new);
|
TRI_FreeCollectionInfoOptions(&new);
|
||||||
|
|
||||||
|
@ -1227,7 +1229,7 @@ TRI_collection_t* TRI_OpenCollection (TRI_vocbase_t* vocbase,
|
||||||
ok = CheckCollection(collection);
|
ok = CheckCollection(collection);
|
||||||
|
|
||||||
if (! ok) {
|
if (! ok) {
|
||||||
LOG_ERROR("cannot open '%s', check failed", collection->_directory);
|
LOG_DEBUG("cannot open '%s', check failed", collection->_directory);
|
||||||
|
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, collection->_directory);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, collection->_directory);
|
||||||
|
|
||||||
|
|
|
@ -351,7 +351,8 @@ int TRI_LoadCollectionInfo (char const*,
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int TRI_SaveCollectionInfo (char const*,
|
int TRI_SaveCollectionInfo (char const*,
|
||||||
const TRI_col_info_t* const);
|
const TRI_col_info_t* const,
|
||||||
|
const bool);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief updates the parameter info block
|
/// @brief updates the parameter info block
|
||||||
|
|
|
@ -1464,13 +1464,13 @@ static bool OpenIterator (TRI_df_marker_t const* marker, void* data, TRI_datafil
|
||||||
// it is an update, but only if found has a smaller revision identifier
|
// it is an update, but only if found has a smaller revision identifier
|
||||||
else if (found->_rid < d->_rid || (found->_rid == d->_rid && found->_fid <= datafile->_fid)) {
|
else if (found->_rid < d->_rid || (found->_rid == d->_rid && found->_fid <= datafile->_fid)) {
|
||||||
TRI_doc_mptr_t* newHeader;
|
TRI_doc_mptr_t* newHeader;
|
||||||
TRI_doc_mptr_t oldData;
|
//TRI_doc_mptr_t oldData;
|
||||||
|
|
||||||
// delete old entries
|
// delete old entries
|
||||||
DeleteSecondaryIndexes(collection, found);
|
DeleteSecondaryIndexes(collection, found);
|
||||||
|
|
||||||
// save the old data
|
// save the old data
|
||||||
oldData = *found;
|
// oldData = *found;
|
||||||
|
|
||||||
// TODO: this will be identical for non-transactional collections only
|
// TODO: this will be identical for non-transactional collections only
|
||||||
newHeader = CONST_CAST(found);
|
newHeader = CONST_CAST(found);
|
||||||
|
@ -1943,7 +1943,7 @@ TRI_document_collection_t* TRI_CreateDocumentCollection (TRI_vocbase_t* vocbase,
|
||||||
document->base._keyGenerator = keyGenerator;
|
document->base._keyGenerator = keyGenerator;
|
||||||
|
|
||||||
// save the parameter block (within create, no need to lock)
|
// save the parameter block (within create, no need to lock)
|
||||||
res = TRI_SaveCollectionInfo(collection->_directory, parameter);
|
res = TRI_SaveCollectionInfo(collection->_directory, parameter, vocbase->_forceSyncProperties);
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
// TODO: shouldn't we destroy &document->_allIndexes, free document->_headers etc.?
|
// TODO: shouldn't we destroy &document->_allIndexes, free document->_headers etc.?
|
||||||
LOG_ERROR("cannot save collection parameters in directory '%s': '%s'", collection->_directory, TRI_last_error());
|
LOG_ERROR("cannot save collection parameters in directory '%s': '%s'", collection->_directory, TRI_last_error());
|
||||||
|
@ -2054,7 +2054,7 @@ TRI_document_collection_t* TRI_OpenDocumentCollection (TRI_vocbase_t* vocbase, c
|
||||||
|
|
||||||
// then the shape collection
|
// then the shape collection
|
||||||
shapes = TRI_Concatenate2File(collection->_directory, "SHAPES");
|
shapes = TRI_Concatenate2File(collection->_directory, "SHAPES");
|
||||||
if (! shapes) {
|
if (shapes == NULL) {
|
||||||
TRI_CloseCollection(collection);
|
TRI_CloseCollection(collection);
|
||||||
TRI_FreeCollection(collection);
|
TRI_FreeCollection(collection);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -226,7 +226,7 @@ int TRI_SaveIndex (TRI_primary_collection_t* collection, TRI_index_t* idx) {
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
|
||||||
|
|
||||||
// and save
|
// and save
|
||||||
ok = TRI_SaveJson(filename, json);
|
ok = TRI_SaveJson(filename, json, collection->base._vocbase->_forceSyncProperties);
|
||||||
|
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
||||||
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
||||||
|
@ -2316,7 +2316,7 @@ TRI_index_t* TRI_CreateFulltextIndex (struct TRI_primary_collection_s* collectio
|
||||||
|
|
||||||
fts = TRI_CreateFtsIndex(2048, 1, 1);
|
fts = TRI_CreateFtsIndex(2048, 1, 1);
|
||||||
if (fts == NULL) {
|
if (fts == NULL) {
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, fulltextIndex);
|
TRI_Free(TRI_CORE_MEM_ZONE, fulltextIndex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,7 @@ int TRI_WriteServerId (char const* filename) {
|
||||||
|
|
||||||
// save json info to file
|
// save json info to file
|
||||||
LOG_DEBUG("Writing server id to file '%s'", filename);
|
LOG_DEBUG("Writing server id to file '%s'", filename);
|
||||||
ok = TRI_SaveJson(filename, json);
|
ok = TRI_SaveJson(filename, json, true);
|
||||||
|
|
||||||
if (! ok) {
|
if (! ok) {
|
||||||
LOG_ERROR("could not save shutdown information in file '%s': %s", filename, TRI_last_error());
|
LOG_ERROR("could not save shutdown information in file '%s': %s", filename, TRI_last_error());
|
||||||
|
|
|
@ -186,14 +186,17 @@ TRI_transaction_list_t;
|
||||||
|
|
||||||
typedef struct TRI_transaction_context_s {
|
typedef struct TRI_transaction_context_s {
|
||||||
TRI_transaction_id_t _id; // last transaction id assigned
|
TRI_transaction_id_t _id; // last transaction id assigned
|
||||||
#if 0
|
|
||||||
|
TRI_read_write_lock_t _rwLock; // lock used to either simulatensously read this structure,
|
||||||
|
// or uniquely modify this structure
|
||||||
|
#if 0
|
||||||
TRI_mutex_t _lock; // lock used to serialize starting/stopping transactions
|
TRI_mutex_t _lock; // lock used to serialize starting/stopping transactions
|
||||||
TRI_mutex_t _collectionLock; // lock used when accessing _collections
|
TRI_mutex_t _collectionLock; // lock used when accessing _collections
|
||||||
TRI_transaction_list_t _readTransactions; // global list of currently ongoing read transactions
|
TRI_transaction_list_t _readTransactions; // global list of currently ongoing read transactions
|
||||||
TRI_transaction_list_t _writeTransactions; // global list of currently ongoing write transactions
|
TRI_transaction_list_t _writeTransactions; // global list of currently ongoing write transactions
|
||||||
TRI_associative_pointer_t _collections; // list of collections (TRI_transaction_collection_global_t)
|
TRI_associative_pointer_t _collections; // list of collections (TRI_transaction_collection_global_t)
|
||||||
#endif
|
#endif
|
||||||
struct TRI_vocbase_s* _vocbase; // pointer to vocbase
|
struct TRI_vocbase_s* _vocbase; // pointer to vocbase
|
||||||
}
|
}
|
||||||
TRI_transaction_context_t;
|
TRI_transaction_context_t;
|
||||||
|
|
||||||
|
|
|
@ -960,7 +960,7 @@ TRI_shaper_t* TRI_CreateVocShaper (TRI_vocbase_t* vocbase,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = TRI_SaveCollectionInfo(collection->base._directory, ¶meter);
|
res = TRI_SaveCollectionInfo(collection->base._directory, ¶meter, vocbase->_forceSyncProperties);
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
LOG_ERROR("cannot save collection parameters in directory '%s': '%s'", collection->base._directory, TRI_last_error());
|
LOG_ERROR("cannot save collection parameters in directory '%s': '%s'", collection->base._directory, TRI_last_error());
|
||||||
TRI_FreeVocShaper(&shaper->base);
|
TRI_FreeVocShaper(&shaper->base);
|
||||||
|
|
|
@ -1741,7 +1741,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collec
|
||||||
if (! info._deleted) {
|
if (! info._deleted) {
|
||||||
info._deleted = true;
|
info._deleted = true;
|
||||||
|
|
||||||
res = TRI_SaveCollectionInfo(collection->_path, &info);
|
res = TRI_SaveCollectionInfo(collection->_path, &info, vocbase->_forceSyncProperties);
|
||||||
TRI_FreeCollectionInfoOptions(&info);
|
TRI_FreeCollectionInfoOptions(&info);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
@ -1894,7 +1894,7 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll
|
||||||
|
|
||||||
TRI_CopyString(info._name, newName, sizeof(info._name));
|
TRI_CopyString(info._name, newName, sizeof(info._name));
|
||||||
|
|
||||||
res = TRI_SaveCollectionInfo(collection->_path, &info);
|
res = TRI_SaveCollectionInfo(collection->_path, &info, vocbase->_forceSyncProperties);
|
||||||
TRI_FreeCollectionInfoOptions(&info);
|
TRI_FreeCollectionInfoOptions(&info);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
|
|
@ -367,13 +367,13 @@ typedef uint32_t TRI_col_type_t;
|
||||||
|
|
||||||
typedef struct TRI_vocbase_s {
|
typedef struct TRI_vocbase_s {
|
||||||
char* _path;
|
char* _path;
|
||||||
char* _lockFile;
|
|
||||||
|
|
||||||
bool _authInfoLoaded; // flag indicating whether the authentication info was loaded successfully
|
bool _authInfoLoaded; // flag indicating whether the authentication info was loaded successfully
|
||||||
bool _removeOnDrop; // wipe collection from disk after dropping
|
bool _removeOnDrop; // wipe collection from disk after dropping
|
||||||
bool _removeOnCompacted; // wipe datafile from disk after compaction
|
bool _removeOnCompacted; // wipe datafile from disk after compaction
|
||||||
bool _defaultWaitForSync;
|
bool _defaultWaitForSync;
|
||||||
bool _forceSyncShapes; // force synching of shape data to disk
|
bool _forceSyncShapes; // force syncing of shape data to disk
|
||||||
|
bool _forceSyncProperties; // force syncing of shape data to disk
|
||||||
|
|
||||||
TRI_voc_size_t _defaultMaximalSize;
|
TRI_voc_size_t _defaultMaximalSize;
|
||||||
|
|
||||||
|
@ -406,6 +406,8 @@ typedef struct TRI_vocbase_s {
|
||||||
TRI_condition_t _cleanupCondition;
|
TRI_condition_t _cleanupCondition;
|
||||||
TRI_condition_t _syncWaitersCondition;
|
TRI_condition_t _syncWaitersCondition;
|
||||||
int64_t _syncWaiters;
|
int64_t _syncWaiters;
|
||||||
|
|
||||||
|
char* _lockFile;
|
||||||
}
|
}
|
||||||
TRI_vocbase_t;
|
TRI_vocbase_t;
|
||||||
|
|
||||||
|
|
|
@ -234,12 +234,16 @@ table.dataTable thead th {
|
||||||
color:#666666;
|
color:#666666;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-backward, .icon-forward {
|
.icon-backward, .icon-forward, .icon-step-backward, .icon-step-forward {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 3px;
|
top: 3px;
|
||||||
left:10px;
|
left:10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.prePagi {
|
||||||
|
margin-right: -5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
border-radius:0;
|
border-radius:0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -471,9 +471,10 @@ ModuleCache["/internal"] = new Module("/internal");
|
||||||
internal.printShell.apply(internal.printShell, arguments);
|
internal.printShell.apply(internal.printShell, arguments);
|
||||||
|
|
||||||
// flush buffer
|
// flush buffer
|
||||||
$('#shellContent').append('<p class="shellSuccess">'
|
//$('#shellContent').append('<p class="shellSuccess">'
|
||||||
+ internal.browserOutputBuffer
|
// + internal.browserOutputBuffer
|
||||||
+ '</p>');
|
// + '</p>');
|
||||||
|
jqconsole.Write('==> ' + internal.browserOutputBuffer + '\n', 'jssuccess');
|
||||||
internal.browserOutputBuffer = "";
|
internal.browserOutputBuffer = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,10 @@
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div id="documentsToolbarF" class="pagination pagination-small pagination-centered"></div>
|
<div id="documentsToolbarFL">
|
||||||
|
<div id="documentsToolbarF" class="pagination pagination-small pagination-centered">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Delete Modal -->
|
<!-- Delete Modal -->
|
||||||
<div id="docDeleteModal" style="display:none" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
<div id="docDeleteModal" style="display:none" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||||
|
@ -49,12 +51,12 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th class="collectionTh">_from:</th>
|
<th class="collectionTh">_from:</th>
|
||||||
<th><input type="text" id="new-document-from" name="from" value=""/></th>
|
<th><input type="text" id="new-document-from" name="from" value=""/></th>
|
||||||
<th><a class="modalTooltips" title="document handle of the linked vertex (incoming relation)"><i class="icon-info-sign"></i></a></th>
|
<th><a class="modalTooltips" title="Document _id: document handle of the linked vertex (incoming relation)"><i class="icon-info-sign"></i></a></th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="collectionTh">_to:</th>
|
<th class="collectionTh">_to:</th>
|
||||||
<th><input type="text" id="new-document-to" name="to" value=""/></th>
|
<th><input type="text" id="new-document-to" name="to" value=""/></th>
|
||||||
<th><a class="modalTooltips" title="document handle of the linked vertex (outgoing relation)"><i class="icon-info-sign"></i></a></th>
|
<th><a class="modalTooltips" title="Document _id: document handle of the linked vertex (outgoing relation)"><i class="icon-info-sign"></i></a></th>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,6 +7,7 @@ var aboutView = Backbone.View.extend({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
$(this.el).html(this.template.text);
|
$(this.el).html(this.template.text);
|
||||||
|
$.gritter.removeAll();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,13 @@ var collectionView = Backbone.View.extend({
|
||||||
"hidden #change-collection" : "hidden",
|
"hidden #change-collection" : "hidden",
|
||||||
"click #delete-modified-collection" : "deleteCollection",
|
"click #delete-modified-collection" : "deleteCollection",
|
||||||
"click #load-modified-collection" : "loadCollection",
|
"click #load-modified-collection" : "loadCollection",
|
||||||
"click #unload-modified-collection" : "unloadCollection"
|
"click #unload-modified-collection" : "unloadCollection",
|
||||||
|
"keydown" : "listenKey"
|
||||||
|
},
|
||||||
|
listenKey: function(e) {
|
||||||
|
if (e.keyCode == 13) {
|
||||||
|
this.saveModifiedCollection();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
hidden: function () {
|
hidden: function () {
|
||||||
window.location.hash = "#collection/";
|
window.location.hash = "#collection/";
|
||||||
|
|
|
@ -16,6 +16,7 @@ var dashboardView = Backbone.View.extend({
|
||||||
template: new EJS({url: '/_admin/html/js/templates/dashboardView.ejs'}),
|
template: new EJS({url: '/_admin/html/js/templates/dashboardView.ejs'}),
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
$.gritter.removeAll();
|
||||||
$(this.el).html(this.template.text);
|
$(this.el).html(this.template.text);
|
||||||
this.updateCollectionsStats();
|
this.updateCollectionsStats();
|
||||||
this.renderCollections();
|
this.renderCollections();
|
||||||
|
|
|
@ -3,6 +3,7 @@ var documentView = Backbone.View.extend({
|
||||||
table: '#documentTableID',
|
table: '#documentTableID',
|
||||||
colid: 0,
|
colid: 0,
|
||||||
docid: 0,
|
docid: 0,
|
||||||
|
currentKey: 0,
|
||||||
|
|
||||||
init: function () {
|
init: function () {
|
||||||
this.initTable();
|
this.initTable();
|
||||||
|
@ -15,7 +16,35 @@ var documentView = Backbone.View.extend({
|
||||||
"click #sourceView" : "sourceView",
|
"click #sourceView" : "sourceView",
|
||||||
"click #editFirstRow" : "editFirst",
|
"click #editFirstRow" : "editFirst",
|
||||||
"click #documentTableID tr" : "clicked",
|
"click #documentTableID tr" : "clicked",
|
||||||
"click #editSecondRow" : "editSecond"
|
"click #editSecondRow" : "editSecond",
|
||||||
|
"keydown .sorting_1" : "listenKey",
|
||||||
|
"keydown" : "listenGlobalKey",
|
||||||
|
"focusout textarea" : "checkFocus"
|
||||||
|
},
|
||||||
|
|
||||||
|
checkFocus: function(e) {
|
||||||
|
//check if new row has to be saved
|
||||||
|
var self = this;
|
||||||
|
var data = $(this.table).dataTable().fnGetData();
|
||||||
|
$.each(data, function(key, val) {
|
||||||
|
if (val[0] === self.currentKey) {
|
||||||
|
$(self.table).dataTable().fnDeleteRow( key );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
listenGlobalKey: function(e) {
|
||||||
|
if (e.keyCode === 27) {
|
||||||
|
this.checkFocus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
listenKey: function(e) {
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
console.log('enter');
|
||||||
|
$('.btn-success').click();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
template: new EJS({url: '/_admin/html/js/templates/documentView.ejs'}),
|
template: new EJS({url: '/_admin/html/js/templates/documentView.ejs'}),
|
||||||
|
@ -147,9 +176,11 @@ var documentView = Backbone.View.extend({
|
||||||
|
|
||||||
addLine: function () {
|
addLine: function () {
|
||||||
var randomKey = arangoHelper.getRandomToken();
|
var randomKey = arangoHelper.getRandomToken();
|
||||||
|
var self = this;
|
||||||
|
self.currentKey = "zkey"+randomKey;
|
||||||
$(this.table).dataTable().fnAddData(
|
$(this.table).dataTable().fnAddData(
|
||||||
[
|
[
|
||||||
"zkey"+randomKey,
|
self.currentKey,
|
||||||
'<i class="icon-edit" id="editFirstRow"></i>',
|
'<i class="icon-edit" id="editFirstRow"></i>',
|
||||||
this.value2html("editme"),
|
this.value2html("editme"),
|
||||||
JSON.stringify("editme"),
|
JSON.stringify("editme"),
|
||||||
|
@ -160,8 +191,9 @@ var documentView = Backbone.View.extend({
|
||||||
this.makeEditable();
|
this.makeEditable();
|
||||||
var tableContent = $('table').find('td');
|
var tableContent = $('table').find('td');
|
||||||
$.each(tableContent, function(key, val) {
|
$.each(tableContent, function(key, val) {
|
||||||
if ($(val).text() === "zkey"+randomKey) {
|
if ($(val).text() === self.currentKey) {
|
||||||
$(val).click();
|
$(val).click();
|
||||||
|
$('.jediTextarea textarea').val("");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -258,9 +290,9 @@ var documentView = Backbone.View.extend({
|
||||||
$('.writeable', documentEditTable.fnGetNodes()).editable(function(value, settings) {
|
$('.writeable', documentEditTable.fnGetNodes()).editable(function(value, settings) {
|
||||||
var aPos = documentEditTable.fnGetPosition(this);
|
var aPos = documentEditTable.fnGetPosition(this);
|
||||||
if (aPos[1] == 0) {
|
if (aPos[1] == 0) {
|
||||||
documentEditTable.fnUpdate(value, aPos[0], aPos[1]);
|
documentEditTable.fnUpdate(self.escaped(value), aPos[0], aPos[1]);
|
||||||
self.updateLocalDocumentStorage();
|
self.updateLocalDocumentStorage();
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
if (aPos[1] == 2) {
|
if (aPos[1] == 2) {
|
||||||
var oldContent = JSON.parse(documentEditTable.fnGetData(aPos[0], aPos[1] + 1));
|
var oldContent = JSON.parse(documentEditTable.fnGetData(aPos[0], aPos[1] + 1));
|
||||||
|
@ -282,6 +314,10 @@ var documentView = Backbone.View.extend({
|
||||||
var aPos = documentEditTable.fnGetPosition(this);
|
var aPos = documentEditTable.fnGetPosition(this);
|
||||||
var value = documentEditTable.fnGetData(aPos[0], aPos[1]);
|
var value = documentEditTable.fnGetData(aPos[0], aPos[1]);
|
||||||
if (aPos[1] == 0) {
|
if (aPos[1] == 0) {
|
||||||
|
//check if this row was newly created
|
||||||
|
if (value === self.currentKey) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
if (aPos[1] == 2) {
|
if (aPos[1] == 2) {
|
||||||
|
@ -301,11 +337,11 @@ var documentView = Backbone.View.extend({
|
||||||
cssclass : 'jediTextarea',
|
cssclass : 'jediTextarea',
|
||||||
submitcssclass: 'btn btn-success pull-right',
|
submitcssclass: 'btn btn-success pull-right',
|
||||||
cancelcssclass: 'btn btn-danger pull-right',
|
cancelcssclass: 'btn btn-danger pull-right',
|
||||||
cancel: 'Cancel',
|
cancel: '<button class="cancelButton btn btn-danger pull-right">Cancel</button">',
|
||||||
submit: 'Save',
|
submit: 'Save',
|
||||||
onblur: 'cancel',
|
onblur: 'cancel',
|
||||||
//style: 'display: inline',
|
|
||||||
autogrow: {lineHeight: 16, minHeight: 30}
|
autogrow: {lineHeight: 16, minHeight: 30}
|
||||||
|
//style: 'display: inline',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getTypedValue: function (value) {
|
getTypedValue: function (value) {
|
||||||
|
|
|
@ -24,7 +24,14 @@ var documentsView = Backbone.View.extend({
|
||||||
"click #documents_last" : "lastDocuments",
|
"click #documents_last" : "lastDocuments",
|
||||||
"click #documents_prev" : "prevDocuments",
|
"click #documents_prev" : "prevDocuments",
|
||||||
"click #documents_next" : "nextDocuments",
|
"click #documents_next" : "nextDocuments",
|
||||||
"click #confirmDeleteBtn" : "confirmDelete"
|
"click #confirmDeleteBtn" : "confirmDelete",
|
||||||
|
"keyup .modal-body" : "listenKey"
|
||||||
|
},
|
||||||
|
|
||||||
|
listenKey: function (e) {
|
||||||
|
if(e.keyCode === 13){
|
||||||
|
this.addEdge();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
buildCollectionLink : function (collection) {
|
buildCollectionLink : function (collection) {
|
||||||
|
@ -77,6 +84,14 @@ var documentsView = Backbone.View.extend({
|
||||||
var collid = window.location.hash.split("/")[1];
|
var collid = window.location.hash.split("/")[1];
|
||||||
var from = $('#new-document-from').val();
|
var from = $('#new-document-from').val();
|
||||||
var to = $('#new-document-to').val();
|
var to = $('#new-document-to').val();
|
||||||
|
if (from === '') {
|
||||||
|
arangoHelper.arangoNotification('From paramater is missing');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (to === '') {
|
||||||
|
arangoHelper.arangoNotification('To parameter is missing');
|
||||||
|
return;
|
||||||
|
}
|
||||||
var result = window.arangoDocumentStore.createTypeEdge(collid, from, to);
|
var result = window.arangoDocumentStore.createTypeEdge(collid, from, to);
|
||||||
|
|
||||||
if (result !== false) {
|
if (result !== false) {
|
||||||
|
@ -85,7 +100,6 @@ var documentsView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
//Error
|
//Error
|
||||||
else {
|
else {
|
||||||
$('#edgeCreateModal').modal('hide');
|
|
||||||
arangoHelper.arangoError('Creating edge failed');
|
arangoHelper.arangoError('Creating edge failed');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -241,6 +255,7 @@ var documentsView = Backbone.View.extend({
|
||||||
if (this.collectionContext.next === null) {
|
if (this.collectionContext.next === null) {
|
||||||
$('#collectionNext').parent().addClass('disabledPag');
|
$('#collectionNext').parent().addClass('disabledPag');
|
||||||
}
|
}
|
||||||
|
$.gritter.removeAll();
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
@ -259,7 +274,9 @@ var documentsView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
target.pagination(options);
|
target.pagination(options);
|
||||||
$('#documentsToolbarF2').append('<a>Total: ' + this.documentsCount + ' documents</a>');
|
$('#documentsToolbarF').prepend('<ul class="prePagi"><li><a id="documents_first"><i class="icon icon-step-backward"></i></a></li></ul>');
|
||||||
|
$('#documentsToolbarF').append('<ul class="lasPagi"><li><a id="documents_last"><i class="icon icon-step-forward"></i></a></li></ul>');
|
||||||
|
//$('#documentsToolbarF2').append('<a>Total: ' + this.documentsCount + ' documents</a>');
|
||||||
},
|
},
|
||||||
breadcrumb: function () {
|
breadcrumb: function () {
|
||||||
var name = window.location.hash.split("/")[1];
|
var name = window.location.hash.split("/")[1];
|
||||||
|
|
|
@ -134,6 +134,7 @@ var logsView = Backbone.View.extend({
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
$(this.el).html(this.template.text);
|
$(this.el).html(this.template.text);
|
||||||
|
$.gritter.removeAll();
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
renderPagination: function (totalPages, currentPage) {
|
renderPagination: function (totalPages, currentPage) {
|
||||||
|
@ -160,6 +161,8 @@ var logsView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
target.pagination(options);
|
target.pagination(options);
|
||||||
|
$('#logtestdiv').prepend('<ul class="prePagi"><li><a id="logTableID_first"><i class="icon icon-step-backward"></i></a></li></ul>');
|
||||||
|
$('#logtestdiv').append('<ul class="lasPagi"><li><a id="logTableID_last"><i class="icon icon-step-forward"></i></a></li></ul>');
|
||||||
},
|
},
|
||||||
drawTable: function () {
|
drawTable: function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
|
@ -23,6 +23,13 @@ var newCollectionView = Backbone.View.extend({
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
"click #save-new-collection" : "saveNewCollection",
|
"click #save-new-collection" : "saveNewCollection",
|
||||||
|
"keydown" : "listenKey"
|
||||||
|
},
|
||||||
|
|
||||||
|
listenKey: function(e) {
|
||||||
|
if (e.keyCode == 13) {
|
||||||
|
this.saveNewCollection();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
hidden: function () {
|
hidden: function () {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
var queryView = Backbone.View.extend({
|
var queryView = Backbone.View.extend({
|
||||||
el: '#content',
|
el: '#content',
|
||||||
init: function () {
|
initialize: function () {
|
||||||
|
localStorage.setItem("queryContent", "");
|
||||||
|
localStorage.setItem("queryOutput", "");
|
||||||
},
|
},
|
||||||
events: {
|
events: {
|
||||||
'click #submitQueryIcon' : 'submitQuery',
|
'click #submitQueryIcon' : 'submitQuery',
|
||||||
|
@ -14,6 +16,7 @@ var queryView = Backbone.View.extend({
|
||||||
template: new EJS({url: '/_admin/html/js/templates/queryView.ejs'}),
|
template: new EJS({url: '/_admin/html/js/templates/queryView.ejs'}),
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
|
||||||
$(this.el).html(this.template.text);
|
$(this.el).html(this.template.text);
|
||||||
var editor = ace.edit("aqlEditor");
|
var editor = ace.edit("aqlEditor");
|
||||||
var editor2 = ace.edit("queryOutput");
|
var editor2 = ace.edit("queryOutput");
|
||||||
|
@ -47,6 +50,15 @@ var queryView = Backbone.View.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#aqlEditor .ace_text-input').focus();
|
$('#aqlEditor .ace_text-input').focus();
|
||||||
|
$.gritter.removeAll();
|
||||||
|
|
||||||
|
if(typeof(Storage)!=="undefined") {
|
||||||
|
var queryContent = localStorage.getItem("queryContent");
|
||||||
|
var queryOutput = localStorage.getItem("queryOutput");
|
||||||
|
editor.setValue(queryContent);
|
||||||
|
console.log(queryOutput);
|
||||||
|
editor2.setValue(queryOutput);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
submitQuery: function() {
|
submitQuery: function() {
|
||||||
|
@ -75,6 +87,11 @@ var queryView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(typeof(Storage) !== "undefined") {
|
||||||
|
localStorage.setItem("queryContent", editor.getValue());
|
||||||
|
localStorage.setItem("queryOutput", editor2.getValue());
|
||||||
|
}
|
||||||
},
|
},
|
||||||
FormatJSON: function(oData, sIndent) {
|
FormatJSON: function(oData, sIndent) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
|
@ -16,6 +16,7 @@ var shellView = Backbone.View.extend({
|
||||||
});
|
});
|
||||||
$("#shell_workspace").trigger("resize", [ 200 ]);
|
$("#shell_workspace").trigger("resize", [ 200 ]);
|
||||||
$('.vsplitbar').append('<div id="editor-run"><img src="img/right_icon.png"></img></div>');
|
$('.vsplitbar').append('<div id="editor-run"><img src="img/right_icon.png"></img></div>');
|
||||||
|
$.gritter.removeAll();
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
renderEditor: function () {
|
renderEditor: function () {
|
||||||
|
@ -95,13 +96,14 @@ var shellView = Backbone.View.extend({
|
||||||
},
|
},
|
||||||
evaloutput: function (data) {
|
evaloutput: function (data) {
|
||||||
try {
|
try {
|
||||||
var result = eval(data);
|
var result = eval(data);
|
||||||
if (result !== undefined) {
|
if (result !== undefined) {
|
||||||
print(result);
|
print(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
$('#shellContent').append('<p class="shellError">Error:' + e + '</p>');
|
//$('#shellContent').append('<p class="shellError">Error:' + e + '</p>');
|
||||||
|
jqconsole.Write('ReferenceError: ' + e + '\n', 'jserror');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ function CompactionSuite () {
|
||||||
maxWait = 750;
|
maxWait = 750;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
maxWait = 75;
|
maxWait = 90;
|
||||||
}
|
}
|
||||||
|
|
||||||
waited = 0;
|
waited = 0;
|
||||||
|
|
|
@ -223,8 +223,8 @@ namespace triagens {
|
||||||
for (size_t i = 1; i < N + 1; ++i) {
|
for (size_t i = 1; i < N + 1; ++i) {
|
||||||
T = T + StatisticsNonces[l2age][i];
|
T = T + StatisticsNonces[l2age][i];
|
||||||
coeff = coeff * (N - i + 1) / i;
|
coeff = coeff * (N - i + 1) / i;
|
||||||
S0 = S0 * pow(StatisticsNonces[l2age][i] / coeff, (4 * N + 2 - 6 * i) / (N * N - N));
|
S0 = S0 * pow((double)(StatisticsNonces[l2age][i] / coeff), (double)((4 * N + 2 - 6 * i) / (N * N - N)));
|
||||||
x = x * pow(StatisticsNonces[l2age][i] / coeff, (12 * i - 6 * N - 6) / (N * N * N - N));
|
x = x * pow((double)(StatisticsNonces[l2age][i] / coeff), (double)((12 * i - 6 * N - 6) / (N * N * N - N)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Statistics current;
|
Statistics current;
|
||||||
|
|
|
@ -196,7 +196,7 @@ bool Thread::start (ConditionVariable * finishedCondition) {
|
||||||
|
|
||||||
void Thread::stop () {
|
void Thread::stop () {
|
||||||
if (_running != 0) {
|
if (_running != 0) {
|
||||||
LOGGER_TRACE("trying to cancel (aka stop) the thread " << _name);
|
LOGGER_TRACE("trying to cancel (aka stop) the thread '" << _name << "'");
|
||||||
TRI_StopThread(&_thread);
|
TRI_StopThread(&_thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ void Thread::shutdown () {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_running != 0) {
|
if (_running != 0) {
|
||||||
LOGGER_TRACE("trying to cancel (aka stop) the thread " << _name);
|
LOGGER_TRACE("trying to cancel (aka stop) the thread '" << _name << "'");
|
||||||
TRI_StopThread(&_thread);
|
TRI_StopThread(&_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ void Thread::allowAsynchronousCancelation () {
|
||||||
if (_started) {
|
if (_started) {
|
||||||
if (_running) {
|
if (_running) {
|
||||||
if (TRI_IsSelfThread(&_thread)) {
|
if (TRI_IsSelfThread(&_thread)) {
|
||||||
LOGGER_DEBUG("set asynchronous cancelation for " << _name);
|
LOGGER_DEBUG("set asynchronous cancelation for thread '" << _name << "'");
|
||||||
TRI_AllowCancelation();
|
TRI_AllowCancelation();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -295,7 +295,7 @@ void Thread::allowAsynchronousCancelation () {
|
||||||
|
|
||||||
void Thread::runMe () {
|
void Thread::runMe () {
|
||||||
if (_asynchronousCancelation) {
|
if (_asynchronousCancelation) {
|
||||||
LOGGER_DEBUG("set asynchronous cancelation for " << _name);
|
LOGGER_DEBUG("set asynchronous cancelation for thread '" << _name << "'");
|
||||||
TRI_AllowCancelation();
|
TRI_AllowCancelation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,6 +306,7 @@ void Thread::runMe () {
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
_running = 0;
|
_running = 0;
|
||||||
|
LOGGER_WARNING("exception caught in thread '" << _name << "'");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,24 +101,27 @@ static int StringifyJson (TRI_memory_zone_t* zone,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = TRI_EscapeUtf8StringZ(zone,
|
if (object->_value._string.length > 0) {
|
||||||
object->_value._string.data,
|
// optimisation for the empty string
|
||||||
object->_value._string.length - 1,
|
ptr = TRI_EscapeUtf8StringZ(zone,
|
||||||
false,
|
object->_value._string.data,
|
||||||
&outLength);
|
object->_value._string.length - 1,
|
||||||
|
false,
|
||||||
|
&outLength);
|
||||||
|
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
return TRI_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = TRI_AppendString2StringBuffer(buffer, ptr, outLength);
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_Free(zone, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = TRI_AppendString2StringBuffer(buffer, ptr, outLength);
|
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRI_Free(zone, ptr);
|
|
||||||
|
|
||||||
res = TRI_AppendCharStringBuffer(buffer, '\"');
|
res = TRI_AppendCharStringBuffer(buffer, '\"');
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
@ -870,8 +873,9 @@ bool TRI_PrintJson (int fd, TRI_json_t const* object) {
|
||||||
/// @brief saves a json object
|
/// @brief saves a json object
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool TRI_SaveJson (char const* filename, TRI_json_t const* object) {
|
bool TRI_SaveJson (char const* filename,
|
||||||
bool ok;
|
TRI_json_t const* object,
|
||||||
|
const bool syncFile) {
|
||||||
char* tmp;
|
char* tmp;
|
||||||
int fd;
|
int fd;
|
||||||
int res;
|
int res;
|
||||||
|
@ -892,9 +896,7 @@ bool TRI_SaveJson (char const* filename, TRI_json_t const* object) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = TRI_PrintJson(fd, object);
|
if (! TRI_PrintJson(fd, object)) {
|
||||||
|
|
||||||
if (! ok) {
|
|
||||||
TRI_set_errno(TRI_ERROR_SYS_ERROR);
|
TRI_set_errno(TRI_ERROR_SYS_ERROR);
|
||||||
LOG_ERROR("cannot write to json file '%s': '%s'", tmp, TRI_LAST_ERROR_STR);
|
LOG_ERROR("cannot write to json file '%s': '%s'", tmp, TRI_LAST_ERROR_STR);
|
||||||
TRI_UnlinkFile(tmp);
|
TRI_UnlinkFile(tmp);
|
||||||
|
@ -912,14 +914,14 @@ bool TRI_SaveJson (char const* filename, TRI_json_t const* object) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = TRI_fsync(fd);
|
if (syncFile) {
|
||||||
|
if (! TRI_fsync(fd)) {
|
||||||
if (! ok) {
|
TRI_set_errno(TRI_ERROR_SYS_ERROR);
|
||||||
TRI_set_errno(TRI_ERROR_SYS_ERROR);
|
LOG_ERROR("cannot sync saved json '%s': '%s'", tmp, TRI_LAST_ERROR_STR);
|
||||||
LOG_ERROR("cannot sync saved json '%s': '%s'", tmp, TRI_LAST_ERROR_STR);
|
TRI_UnlinkFile(tmp);
|
||||||
TRI_UnlinkFile(tmp);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = TRI_CLOSE(fd);
|
res = TRI_CLOSE(fd);
|
||||||
|
@ -935,15 +937,17 @@ bool TRI_SaveJson (char const* filename, TRI_json_t const* object) {
|
||||||
res = TRI_RenameFile(tmp, filename);
|
res = TRI_RenameFile(tmp, filename);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
TRI_set_errno(res);
|
||||||
LOG_ERROR("cannot rename saved file '%s' to '%s': '%s'", tmp, filename, TRI_LAST_ERROR_STR);
|
LOG_ERROR("cannot rename saved file '%s' to '%s': '%s'", tmp, filename, TRI_LAST_ERROR_STR);
|
||||||
TRI_UnlinkFile(tmp);
|
TRI_UnlinkFile(tmp);
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
|
||||||
|
|
||||||
return res;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
|
||||||
return ok;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -306,7 +306,7 @@ bool TRI_PrintJson (int fd, TRI_json_t const*);
|
||||||
/// @brief saves a json object
|
/// @brief saves a json object
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool TRI_SaveJson (char const* filename, TRI_json_t const*);
|
bool TRI_SaveJson (char const*, TRI_json_t const*, const bool);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief copies a json object into a given buffer
|
/// @brief copies a json object into a given buffer
|
||||||
|
|
|
@ -551,6 +551,60 @@ void TRI_UnlockCondition (TRI_condition_t* cond) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// COMPARE & SWAP operations below for MAC and GNUC
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief atomically compares and swaps 32bit integers
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool TRI_CompareAndSwapInteger32 (volatile long* theValue, int32_t oldValue, int32_t newValue) {
|
||||||
|
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||||
|
return OSAtomicCompareAndSwap32(oldValue, newValue, theValue);
|
||||||
|
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||||
|
return __sync_val_compare_and_swap(theValue, oldValue, newValue);
|
||||||
|
#else
|
||||||
|
#error No TRI_CompareAndSwapInteger32 implementation defined
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief atomically compares and swaps 64bit integers
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool TRI_CompareAndSwapInteger64 (volatile long* theValue, int64_t oldValue, int64_t newValue) {
|
||||||
|
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||||
|
return OSAtomicCompareAndSwap64(oldValue, newValue, theValue);
|
||||||
|
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||||
|
return __sync_val_compare_and_swap(theValue, oldValue, newValue);
|
||||||
|
#else
|
||||||
|
#error No TRI_CompareAndSwapInteger64 implementation defined
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief atomically compares and swaps pointers
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool TRI_CompareAndSwapPointer(void* volatile* theValue, void* oldValue, void* newValue) {
|
||||||
|
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||||
|
return OSAtomicCompareAndSwapPtr(oldValue, newValue, theValue);
|
||||||
|
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||||
|
return __sync_val_compare_and_swap(theValue, oldValue, newValue);
|
||||||
|
#else
|
||||||
|
#error No TRI_CompareAndSwapPointer implementation defined
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -899,6 +899,40 @@ void TRI_UnlockCondition (TRI_condition_t* cond) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// COMPARE & SWAP operations below for windows
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief atomically compares and swaps 32bit integers
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool TRI_CompareAndSwapInteger32 (volatile long* theValue, int32_t oldValue, int32_t newValue) {
|
||||||
|
return ( InterlockedCompareExchange(theValue, newValue, oldValue) == oldValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief atomically compares and swaps 64bit integers
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool TRI_CompareAndSwapInteger64 (volatile long* theValue, int64_t oldValue, int64_t newValue) {
|
||||||
|
return ( InterlockedCompareExchange64(theValue, newValue, oldValue) == oldValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief atomically compares and swaps pointers
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool TRI_CompareAndSwapPointer(void* volatile* theValue, void* oldValue, void* newValue) {
|
||||||
|
return ( InterlcokedCompareExchangEPointer(theValue, newValue, oldValue) == oldValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -373,6 +373,68 @@ void TRI_UnlockCondition (TRI_condition_t* cond);
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- public functions
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup CAS operations
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief performs an atomic compare and swap operation on a 32bit integer.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// .............................................................................
|
||||||
|
// The position of 'theValue' must be aligned on a 32 bit boundary. The function
|
||||||
|
// performs the following atomically: compares the value stored in the position
|
||||||
|
// pointed to by <theValue> with the value of <oldValue>. if the value stored
|
||||||
|
// in position <theValue> is EQUAL to the value of <oldValue>, then the
|
||||||
|
// <newValue> is stored in the position pointed to by <theValue> (true is
|
||||||
|
// returned), otherwise no operation is performed (false is returned).
|
||||||
|
// .............................................................................
|
||||||
|
|
||||||
|
bool TRI_CompareAndSwapInteger32 (volatile long* theValue, int32_t oldValue, int32_t newValue);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief performs an atomic compare and swap operation on a 64bit integer.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// .............................................................................
|
||||||
|
// The position of 'theValue' must be aligned on a 64 bit boundary. This function is
|
||||||
|
// simply the 64bit equivalent of the function above.
|
||||||
|
// .............................................................................
|
||||||
|
|
||||||
|
bool TRI_CompareAndSwapInteger64 (volatile long* theValue, int64_t oldValue, int64_t newValue);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief performs an atomic compare and swap operation on a pointer.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// .............................................................................
|
||||||
|
// On a 32bit machine, the position of 'theValue' must be aligned on a 32 bit
|
||||||
|
// boundary. On a 64bit machine the alignment must be on a 64bit boundary.
|
||||||
|
// The function performs the following atomically: compares the value stored in
|
||||||
|
// the position pointed to by <theValue> with the value of <oldValue>. if the
|
||||||
|
// value stored in position <theValue> is EQUAL to the value of <oldValue>,
|
||||||
|
// then the <newValue> is stored in the position pointed to by <theValue>
|
||||||
|
// (true is returned), otherwise no operation is performed (false is returned).
|
||||||
|
// .............................................................................
|
||||||
|
|
||||||
|
bool TRI_CompareAndSwapPointer(void* volatile* theValue, void* oldValue, void* newValue);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -126,6 +126,10 @@
|
||||||
#define TRI_HAVE_GETLINE 1
|
#define TRI_HAVE_GETLINE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
|
||||||
|
#define TRI_HAVE_GETLINE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if __WORDSIZE == 64
|
#if __WORDSIZE == 64
|
||||||
#define TRI_SIZEOF_SIZE_T 8
|
#define TRI_SIZEOF_SIZE_T 8
|
||||||
#define TRI_ALIGNOF_VOIDP 8
|
#define TRI_ALIGNOF_VOIDP 8
|
||||||
|
|
|
@ -414,12 +414,20 @@ static TRI_json_t* ParseObject (yyscan_t scanner, int c) {
|
||||||
case STRING_CONSTANT: {
|
case STRING_CONSTANT: {
|
||||||
char* ptr;
|
char* ptr;
|
||||||
size_t outLength;
|
size_t outLength;
|
||||||
|
|
||||||
|
if (yyleng <= 2) {
|
||||||
|
// string is empty, use original pointer
|
||||||
|
ptr = yytext + 1;
|
||||||
|
outLength = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// string is not empty, process it
|
||||||
|
ptr = TRI_UnescapeUtf8StringZ(yyextra._memoryZone, yytext + 1, yyleng - 2, &outLength);
|
||||||
|
|
||||||
ptr = TRI_UnescapeUtf8StringZ(yyextra._memoryZone, yytext + 1, yyleng - 2, &outLength);
|
if (ptr == NULL) {
|
||||||
|
yyextra._message = "out-of-memory";
|
||||||
if (ptr == NULL) {
|
return NULL;
|
||||||
yyextra._message = "out-of-memory";
|
}
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = TRI_CreateString2Json(yyextra._memoryZone, ptr, outLength);
|
result = TRI_CreateString2Json(yyextra._memoryZone, ptr, outLength);
|
||||||
|
|
|
@ -280,7 +280,7 @@ static v8::Handle<v8::Value> ParseArray (yyscan_t scanner) {
|
||||||
return scope.Close(v8::Undefined());
|
return scope.Close(v8::Undefined());
|
||||||
}
|
}
|
||||||
|
|
||||||
array->Set(v8::String::New(name), sub);
|
array->Set(v8::String::New(name, outLength), sub);
|
||||||
|
|
||||||
TRI_FreeString(yyextra._memoryZone, name);
|
TRI_FreeString(yyextra._memoryZone, name);
|
||||||
|
|
||||||
|
@ -352,7 +352,15 @@ static v8::Handle<v8::Value> ParseObject (yyscan_t scanner, int c) {
|
||||||
return scope.Close(v8::Number::New(d));
|
return scope.Close(v8::Number::New(d));
|
||||||
|
|
||||||
case STRING_CONSTANT:
|
case STRING_CONSTANT:
|
||||||
ptr = TRI_UnescapeUtf8StringZ(yyextra._memoryZone, yytext + 1, yyleng - 2, &outLength);
|
if (yyleng <= 2) {
|
||||||
|
// string is empty
|
||||||
|
ptr = yytext + 1;
|
||||||
|
outLength = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// string is not empty
|
||||||
|
ptr = TRI_UnescapeUtf8StringZ(yyextra._memoryZone, yytext + 1, yyleng - 2, &outLength);
|
||||||
|
}
|
||||||
|
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
yyextra._message = "out-of-memory";
|
yyextra._message = "out-of-memory";
|
||||||
|
|
|
@ -41,6 +41,9 @@ esac
|
||||||
TRI_BITS="$tr_BITS"
|
TRI_BITS="$tr_BITS"
|
||||||
AC_SUBST(TRI_BITS)
|
AC_SUBST(TRI_BITS)
|
||||||
|
|
||||||
|
CFLAGS="${CFLAGS} -DTRI_BITS=${TRI_BITS}"
|
||||||
|
CXXFLAGS="${CXXFLAGS} -DTRI_BITS=${TRI_BITS}"
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
dnl use automake to generate Makfile.in
|
dnl use automake to generate Makfile.in
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue