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)
|
||||
-----------------
|
||||
|
||||
* 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
|
||||
`/_admin/version` and `/_api/version`. To retrieve this extended information,
|
||||
call the REST APIs with URL parameter `details=true`.
|
||||
|
|
|
@ -143,6 +143,10 @@ the option `--disable-figures`.
|
|||
@anchor CommandLineArangoWaitForSync
|
||||
@copydetails triagens::arango::ArangoServer::_defaultWaitForSync
|
||||
|
||||
@CLEARPAGE
|
||||
@anchor CommandLineArangoForceSyncProperties
|
||||
@copydetails triagens::arango::ArangoServer::_forceSyncProperties
|
||||
|
||||
@CLEARPAGE
|
||||
@anchor CommandLineArangoForceSyncShapes
|
||||
@copydetails triagens::arango::ArangoServer::_forceSyncShapes
|
||||
|
|
|
@ -28,6 +28,7 @@ TOC {#CommandLineTOC}
|
|||
- @ref CommandLineArangoDirectory "database.directory"
|
||||
- @ref CommandLineArangoMaximalJournalSize "database.maximal-journal-size"
|
||||
- @ref CommandLineArangoWaitForSync "database.wait-for-sync"
|
||||
- @ref CommandLineArangoForceSyncProperties "database.force-sync-properties"
|
||||
- @ref CommandLineArangoForceSyncShapes "database.force-sync-shapes"
|
||||
- @ref CommandLineArangoRemoveOnDrop "database.remove-on-compacted"
|
||||
- @ref CommandLineArangoJsGcFrequency "javascript.gc-frequency"
|
||||
|
|
|
@ -77,6 +77,7 @@ SERVER_OPT := \
|
|||
--configuration none \
|
||||
--database.maximal-journal-size 1048576 \
|
||||
--database.force-sync-shapes false \
|
||||
--database.force-sync-properties false \
|
||||
--javascript.action-directory @top_srcdir@/js/actions/system \
|
||||
--javascript.gc-interval 1 \
|
||||
--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
|
||||
}
|
||||
|
||||
if (deescape) {
|
||||
if (deescape && length > 0) {
|
||||
size_t outLength;
|
||||
|
||||
copy = TRI_UnescapeUtf8StringZ(TRI_UNKNOWN_MEM_ZONE, value, length, &outLength);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -92,7 +92,9 @@ static int AllocateSubObjectsHashIndexElement (TRI_hash_index_t const* idx,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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);
|
||||
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) {
|
||||
return TRI_set_errno(TRI_ERROR_ARANGO_UNIQUE_CONSTRAINT_VIOLATED);
|
||||
|
|
|
@ -71,6 +71,8 @@ bin_arangod_SOURCES = \
|
|||
arangod/RestServer/arango.cpp \
|
||||
arangod/SkipLists/skiplist.c \
|
||||
arangod/SkipLists/skiplistIndex.c \
|
||||
arangod/SkipListsEx/skiplistEx.c \
|
||||
arangod/SkipListsEx/skiplistExIndex.c \
|
||||
arangod/V8Server/ApplicationV8.cpp \
|
||||
arangod/V8Server/v8-actions.cpp \
|
||||
arangod/V8Server/v8-query.cpp \
|
||||
|
|
|
@ -181,6 +181,7 @@ ArangoServer::ArangoServer (int argc, char** argv)
|
|||
_defaultMaximalSize(TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE),
|
||||
_defaultWaitForSync(false),
|
||||
_forceSyncShapes(true),
|
||||
_forceSyncProperties(true),
|
||||
_vocbase(0) {
|
||||
|
||||
// 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.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-properties", &_forceSyncProperties, "force syncing of collection properties to disk, will use waitForSync value of collection when turned off")
|
||||
;
|
||||
|
||||
additional["DATABASE Options:help-devel"]
|
||||
|
@ -1074,6 +1076,7 @@ void ArangoServer::openDatabase () {
|
|||
_vocbase->_defaultMaximalSize = _defaultMaximalSize;
|
||||
_vocbase->_defaultWaitForSync = _defaultWaitForSync;
|
||||
_vocbase->_forceSyncShapes = _forceSyncShapes;
|
||||
_vocbase->_forceSyncProperties = _forceSyncProperties;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -347,20 +347,37 @@ namespace triagens {
|
|||
bool _defaultWaitForSync;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief force sync shapes
|
||||
/// @brief force syncing of shape data
|
||||
///
|
||||
/// @CMDOPT{\--database.force-sync-shapes @CA{boolean}}
|
||||
///
|
||||
/// Force syncing of shape data to disk when writing shape information.
|
||||
/// 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
|
||||
/// will always happen, regards of the value of waitForSync.
|
||||
/// will always happen, regardless of the value of waitForSync.
|
||||
///
|
||||
/// The default is @LIT{true}.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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
|
||||
///
|
||||
|
|
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);
|
||||
|
||||
if (!ok || bitarrayIndex == 0) {
|
||||
if (! ok || bitarrayIndex == 0) {
|
||||
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) {
|
||||
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.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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;
|
||||
char* filename;
|
||||
bool ok;
|
||||
|
@ -993,7 +995,7 @@ int TRI_SaveCollectionInfo (char const* path, const TRI_col_info_t* const info)
|
|||
}
|
||||
|
||||
// save json info to file
|
||||
ok = TRI_SaveJson(filename, json);
|
||||
ok = TRI_SaveJson(filename, json, forceSync);
|
||||
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
|
||||
|
||||
if (! ok) {
|
||||
|
@ -1055,7 +1057,7 @@ int TRI_UpdateCollectionInfo (TRI_vocbase_t* vocbase,
|
|||
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_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);
|
||||
|
||||
|
@ -1227,7 +1229,7 @@ TRI_collection_t* TRI_OpenCollection (TRI_vocbase_t* vocbase,
|
|||
ok = CheckCollection(collection);
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -351,7 +351,8 @@ int TRI_LoadCollectionInfo (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
|
||||
|
|
|
@ -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
|
||||
else if (found->_rid < d->_rid || (found->_rid == d->_rid && found->_fid <= datafile->_fid)) {
|
||||
TRI_doc_mptr_t* newHeader;
|
||||
TRI_doc_mptr_t oldData;
|
||||
//TRI_doc_mptr_t oldData;
|
||||
|
||||
// delete old entries
|
||||
DeleteSecondaryIndexes(collection, found);
|
||||
|
||||
// save the old data
|
||||
oldData = *found;
|
||||
// oldData = *found;
|
||||
|
||||
// TODO: this will be identical for non-transactional collections only
|
||||
newHeader = CONST_CAST(found);
|
||||
|
@ -1943,7 +1943,7 @@ TRI_document_collection_t* TRI_CreateDocumentCollection (TRI_vocbase_t* vocbase,
|
|||
document->base._keyGenerator = keyGenerator;
|
||||
|
||||
// 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) {
|
||||
// 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());
|
||||
|
@ -2054,7 +2054,7 @@ TRI_document_collection_t* TRI_OpenDocumentCollection (TRI_vocbase_t* vocbase, c
|
|||
|
||||
// then the shape collection
|
||||
shapes = TRI_Concatenate2File(collection->_directory, "SHAPES");
|
||||
if (! shapes) {
|
||||
if (shapes == NULL) {
|
||||
TRI_CloseCollection(collection);
|
||||
TRI_FreeCollection(collection);
|
||||
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);
|
||||
|
||||
// and save
|
||||
ok = TRI_SaveJson(filename, json);
|
||||
ok = TRI_SaveJson(filename, json, collection->base._vocbase->_forceSyncProperties);
|
||||
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
||||
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);
|
||||
if (fts == NULL) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, fulltextIndex);
|
||||
TRI_Free(TRI_CORE_MEM_ZONE, fulltextIndex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -167,7 +167,7 @@ int TRI_WriteServerId (char const* filename) {
|
|||
|
||||
// save json info to file
|
||||
LOG_DEBUG("Writing server id to file '%s'", filename);
|
||||
ok = TRI_SaveJson(filename, json);
|
||||
ok = TRI_SaveJson(filename, json, true);
|
||||
|
||||
if (! ok) {
|
||||
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 {
|
||||
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 _collectionLock; // lock used when accessing _collections
|
||||
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_associative_pointer_t _collections; // list of collections (TRI_transaction_collection_global_t)
|
||||
#endif
|
||||
struct TRI_vocbase_s* _vocbase; // pointer to vocbase
|
||||
struct TRI_vocbase_s* _vocbase; // pointer to vocbase
|
||||
}
|
||||
TRI_transaction_context_t;
|
||||
|
||||
|
|
|
@ -960,7 +960,7 @@ TRI_shaper_t* TRI_CreateVocShaper (TRI_vocbase_t* vocbase,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
res = TRI_SaveCollectionInfo(collection->base._directory, ¶meter);
|
||||
res = TRI_SaveCollectionInfo(collection->base._directory, ¶meter, vocbase->_forceSyncProperties);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_ERROR("cannot save collection parameters in directory '%s': '%s'", collection->base._directory, TRI_last_error());
|
||||
TRI_FreeVocShaper(&shaper->base);
|
||||
|
|
|
@ -1741,7 +1741,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collec
|
|||
if (! info._deleted) {
|
||||
info._deleted = true;
|
||||
|
||||
res = TRI_SaveCollectionInfo(collection->_path, &info);
|
||||
res = TRI_SaveCollectionInfo(collection->_path, &info, vocbase->_forceSyncProperties);
|
||||
TRI_FreeCollectionInfoOptions(&info);
|
||||
|
||||
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));
|
||||
|
||||
res = TRI_SaveCollectionInfo(collection->_path, &info);
|
||||
res = TRI_SaveCollectionInfo(collection->_path, &info, vocbase->_forceSyncProperties);
|
||||
TRI_FreeCollectionInfoOptions(&info);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
|
|
@ -367,13 +367,13 @@ typedef uint32_t TRI_col_type_t;
|
|||
|
||||
typedef struct TRI_vocbase_s {
|
||||
char* _path;
|
||||
char* _lockFile;
|
||||
|
||||
bool _authInfoLoaded; // flag indicating whether the authentication info was loaded successfully
|
||||
bool _removeOnDrop; // wipe collection from disk after dropping
|
||||
bool _removeOnCompacted; // wipe datafile from disk after compaction
|
||||
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;
|
||||
|
||||
|
@ -406,6 +406,8 @@ typedef struct TRI_vocbase_s {
|
|||
TRI_condition_t _cleanupCondition;
|
||||
TRI_condition_t _syncWaitersCondition;
|
||||
int64_t _syncWaiters;
|
||||
|
||||
char* _lockFile;
|
||||
}
|
||||
TRI_vocbase_t;
|
||||
|
||||
|
|
|
@ -234,12 +234,16 @@ table.dataTable thead th {
|
|||
color:#666666;
|
||||
}
|
||||
|
||||
.icon-backward, .icon-forward {
|
||||
.icon-backward, .icon-forward, .icon-step-backward, .icon-step-forward {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left:10px;
|
||||
}
|
||||
|
||||
.prePagi {
|
||||
margin-right: -5px !important;
|
||||
}
|
||||
|
||||
.badge {
|
||||
border-radius:0;
|
||||
}
|
||||
|
|
|
@ -471,9 +471,10 @@ ModuleCache["/internal"] = new Module("/internal");
|
|||
internal.printShell.apply(internal.printShell, arguments);
|
||||
|
||||
// flush buffer
|
||||
$('#shellContent').append('<p class="shellSuccess">'
|
||||
+ internal.browserOutputBuffer
|
||||
+ '</p>');
|
||||
//$('#shellContent').append('<p class="shellSuccess">'
|
||||
// + internal.browserOutputBuffer
|
||||
// + '</p>');
|
||||
jqconsole.Write('==> ' + internal.browserOutputBuffer + '\n', 'jssuccess');
|
||||
internal.browserOutputBuffer = "";
|
||||
};
|
||||
|
||||
|
|
|
@ -20,8 +20,10 @@
|
|||
</thead>
|
||||
</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 -->
|
||||
<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>
|
||||
<th class="collectionTh">_from:</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>
|
||||
<th class="collectionTh">_to:</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>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -7,6 +7,7 @@ var aboutView = Backbone.View.extend({
|
|||
|
||||
render: function() {
|
||||
$(this.el).html(this.template.text);
|
||||
$.gritter.removeAll();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,13 @@ var collectionView = Backbone.View.extend({
|
|||
"hidden #change-collection" : "hidden",
|
||||
"click #delete-modified-collection" : "deleteCollection",
|
||||
"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 () {
|
||||
window.location.hash = "#collection/";
|
||||
|
|
|
@ -16,6 +16,7 @@ var dashboardView = Backbone.View.extend({
|
|||
template: new EJS({url: '/_admin/html/js/templates/dashboardView.ejs'}),
|
||||
|
||||
render: function() {
|
||||
$.gritter.removeAll();
|
||||
$(this.el).html(this.template.text);
|
||||
this.updateCollectionsStats();
|
||||
this.renderCollections();
|
||||
|
|
|
@ -3,6 +3,7 @@ var documentView = Backbone.View.extend({
|
|||
table: '#documentTableID',
|
||||
colid: 0,
|
||||
docid: 0,
|
||||
currentKey: 0,
|
||||
|
||||
init: function () {
|
||||
this.initTable();
|
||||
|
@ -15,7 +16,35 @@ var documentView = Backbone.View.extend({
|
|||
"click #sourceView" : "sourceView",
|
||||
"click #editFirstRow" : "editFirst",
|
||||
"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'}),
|
||||
|
@ -147,9 +176,11 @@ var documentView = Backbone.View.extend({
|
|||
|
||||
addLine: function () {
|
||||
var randomKey = arangoHelper.getRandomToken();
|
||||
var self = this;
|
||||
self.currentKey = "zkey"+randomKey;
|
||||
$(this.table).dataTable().fnAddData(
|
||||
[
|
||||
"zkey"+randomKey,
|
||||
self.currentKey,
|
||||
'<i class="icon-edit" id="editFirstRow"></i>',
|
||||
this.value2html("editme"),
|
||||
JSON.stringify("editme"),
|
||||
|
@ -160,8 +191,9 @@ var documentView = Backbone.View.extend({
|
|||
this.makeEditable();
|
||||
var tableContent = $('table').find('td');
|
||||
$.each(tableContent, function(key, val) {
|
||||
if ($(val).text() === "zkey"+randomKey) {
|
||||
if ($(val).text() === self.currentKey) {
|
||||
$(val).click();
|
||||
$('.jediTextarea textarea').val("");
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
@ -258,9 +290,9 @@ var documentView = Backbone.View.extend({
|
|||
$('.writeable', documentEditTable.fnGetNodes()).editable(function(value, settings) {
|
||||
var aPos = documentEditTable.fnGetPosition(this);
|
||||
if (aPos[1] == 0) {
|
||||
documentEditTable.fnUpdate(value, aPos[0], aPos[1]);
|
||||
self.updateLocalDocumentStorage();
|
||||
return value;
|
||||
documentEditTable.fnUpdate(self.escaped(value), aPos[0], aPos[1]);
|
||||
self.updateLocalDocumentStorage();
|
||||
return value;
|
||||
}
|
||||
if (aPos[1] == 2) {
|
||||
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 value = documentEditTable.fnGetData(aPos[0], aPos[1]);
|
||||
if (aPos[1] == 0) {
|
||||
//check if this row was newly created
|
||||
if (value === self.currentKey) {
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
if (aPos[1] == 2) {
|
||||
|
@ -301,11 +337,11 @@ var documentView = Backbone.View.extend({
|
|||
cssclass : 'jediTextarea',
|
||||
submitcssclass: 'btn btn-success pull-right',
|
||||
cancelcssclass: 'btn btn-danger pull-right',
|
||||
cancel: 'Cancel',
|
||||
cancel: '<button class="cancelButton btn btn-danger pull-right">Cancel</button">',
|
||||
submit: 'Save',
|
||||
onblur: 'cancel',
|
||||
//style: 'display: inline',
|
||||
autogrow: {lineHeight: 16, minHeight: 30}
|
||||
//style: 'display: inline',
|
||||
});
|
||||
},
|
||||
getTypedValue: function (value) {
|
||||
|
|
|
@ -24,7 +24,14 @@ var documentsView = Backbone.View.extend({
|
|||
"click #documents_last" : "lastDocuments",
|
||||
"click #documents_prev" : "prevDocuments",
|
||||
"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) {
|
||||
|
@ -77,6 +84,14 @@ var documentsView = Backbone.View.extend({
|
|||
var collid = window.location.hash.split("/")[1];
|
||||
var from = $('#new-document-from').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);
|
||||
|
||||
if (result !== false) {
|
||||
|
@ -85,7 +100,6 @@ var documentsView = Backbone.View.extend({
|
|||
}
|
||||
//Error
|
||||
else {
|
||||
$('#edgeCreateModal').modal('hide');
|
||||
arangoHelper.arangoError('Creating edge failed');
|
||||
}
|
||||
},
|
||||
|
@ -241,6 +255,7 @@ var documentsView = Backbone.View.extend({
|
|||
if (this.collectionContext.next === null) {
|
||||
$('#collectionNext').parent().addClass('disabledPag');
|
||||
}
|
||||
$.gritter.removeAll();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
@ -259,7 +274,9 @@ var documentsView = Backbone.View.extend({
|
|||
}
|
||||
};
|
||||
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 () {
|
||||
var name = window.location.hash.split("/")[1];
|
||||
|
|
|
@ -134,6 +134,7 @@ var logsView = Backbone.View.extend({
|
|||
},
|
||||
render: function() {
|
||||
$(this.el).html(this.template.text);
|
||||
$.gritter.removeAll();
|
||||
return this;
|
||||
},
|
||||
renderPagination: function (totalPages, currentPage) {
|
||||
|
@ -160,6 +161,8 @@ var logsView = Backbone.View.extend({
|
|||
}
|
||||
};
|
||||
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 () {
|
||||
var self = this;
|
||||
|
|
|
@ -23,6 +23,13 @@ var newCollectionView = Backbone.View.extend({
|
|||
|
||||
events: {
|
||||
"click #save-new-collection" : "saveNewCollection",
|
||||
"keydown" : "listenKey"
|
||||
},
|
||||
|
||||
listenKey: function(e) {
|
||||
if (e.keyCode == 13) {
|
||||
this.saveNewCollection();
|
||||
}
|
||||
},
|
||||
|
||||
hidden: function () {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
var queryView = Backbone.View.extend({
|
||||
el: '#content',
|
||||
init: function () {
|
||||
initialize: function () {
|
||||
localStorage.setItem("queryContent", "");
|
||||
localStorage.setItem("queryOutput", "");
|
||||
},
|
||||
events: {
|
||||
'click #submitQueryIcon' : 'submitQuery',
|
||||
|
@ -14,6 +16,7 @@ var queryView = Backbone.View.extend({
|
|||
template: new EJS({url: '/_admin/html/js/templates/queryView.ejs'}),
|
||||
|
||||
render: function() {
|
||||
|
||||
$(this.el).html(this.template.text);
|
||||
var editor = ace.edit("aqlEditor");
|
||||
var editor2 = ace.edit("queryOutput");
|
||||
|
@ -47,6 +50,15 @@ var queryView = Backbone.View.extend({
|
|||
});
|
||||
|
||||
$('#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;
|
||||
},
|
||||
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) {
|
||||
var self = this;
|
||||
|
|
|
@ -16,6 +16,7 @@ var shellView = Backbone.View.extend({
|
|||
});
|
||||
$("#shell_workspace").trigger("resize", [ 200 ]);
|
||||
$('.vsplitbar').append('<div id="editor-run"><img src="img/right_icon.png"></img></div>');
|
||||
$.gritter.removeAll();
|
||||
return this;
|
||||
},
|
||||
renderEditor: function () {
|
||||
|
@ -95,13 +96,14 @@ var shellView = Backbone.View.extend({
|
|||
},
|
||||
evaloutput: function (data) {
|
||||
try {
|
||||
var result = eval(data);
|
||||
var result = eval(data);
|
||||
if (result !== undefined) {
|
||||
print(result);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
else {
|
||||
maxWait = 75;
|
||||
maxWait = 90;
|
||||
}
|
||||
|
||||
waited = 0;
|
||||
|
|
|
@ -223,8 +223,8 @@ namespace triagens {
|
|||
for (size_t i = 1; i < N + 1; ++i) {
|
||||
T = T + StatisticsNonces[l2age][i];
|
||||
coeff = coeff * (N - i + 1) / i;
|
||||
S0 = S0 * pow(StatisticsNonces[l2age][i] / coeff, (4 * N + 2 - 6 * i) / (N * N - N));
|
||||
x = x * pow(StatisticsNonces[l2age][i] / coeff, (12 * i - 6 * N - 6) / (N * N * N - N));
|
||||
S0 = S0 * pow((double)(StatisticsNonces[l2age][i] / coeff), (double)((4 * N + 2 - 6 * i) / (N * N - N)));
|
||||
x = x * pow((double)(StatisticsNonces[l2age][i] / coeff), (double)((12 * i - 6 * N - 6) / (N * N * N - N)));
|
||||
}
|
||||
|
||||
Statistics current;
|
||||
|
|
|
@ -196,7 +196,7 @@ bool Thread::start (ConditionVariable * finishedCondition) {
|
|||
|
||||
void Thread::stop () {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ void Thread::shutdown () {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -264,7 +264,7 @@ void Thread::allowAsynchronousCancelation () {
|
|||
if (_started) {
|
||||
if (_running) {
|
||||
if (TRI_IsSelfThread(&_thread)) {
|
||||
LOGGER_DEBUG("set asynchronous cancelation for " << _name);
|
||||
LOGGER_DEBUG("set asynchronous cancelation for thread '" << _name << "'");
|
||||
TRI_AllowCancelation();
|
||||
}
|
||||
else {
|
||||
|
@ -295,7 +295,7 @@ void Thread::allowAsynchronousCancelation () {
|
|||
|
||||
void Thread::runMe () {
|
||||
if (_asynchronousCancelation) {
|
||||
LOGGER_DEBUG("set asynchronous cancelation for " << _name);
|
||||
LOGGER_DEBUG("set asynchronous cancelation for thread '" << _name << "'");
|
||||
TRI_AllowCancelation();
|
||||
}
|
||||
|
||||
|
@ -306,6 +306,7 @@ void Thread::runMe () {
|
|||
}
|
||||
catch (...) {
|
||||
_running = 0;
|
||||
LOGGER_WARNING("exception caught in thread '" << _name << "'");
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,24 +101,27 @@ static int StringifyJson (TRI_memory_zone_t* zone,
|
|||
return res;
|
||||
}
|
||||
|
||||
ptr = TRI_EscapeUtf8StringZ(zone,
|
||||
object->_value._string.data,
|
||||
object->_value._string.length - 1,
|
||||
false,
|
||||
&outLength);
|
||||
if (object->_value._string.length > 0) {
|
||||
// optimisation for the empty string
|
||||
ptr = TRI_EscapeUtf8StringZ(zone,
|
||||
object->_value._string.data,
|
||||
object->_value._string.length - 1,
|
||||
false,
|
||||
&outLength);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
if (ptr == NULL) {
|
||||
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, '\"');
|
||||
|
||||
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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_SaveJson (char const* filename, TRI_json_t const* object) {
|
||||
bool ok;
|
||||
bool TRI_SaveJson (char const* filename,
|
||||
TRI_json_t const* object,
|
||||
const bool syncFile) {
|
||||
char* tmp;
|
||||
int fd;
|
||||
int res;
|
||||
|
@ -892,9 +896,7 @@ bool TRI_SaveJson (char const* filename, TRI_json_t const* object) {
|
|||
return false;
|
||||
}
|
||||
|
||||
ok = TRI_PrintJson(fd, object);
|
||||
|
||||
if (! ok) {
|
||||
if (! TRI_PrintJson(fd, object)) {
|
||||
TRI_set_errno(TRI_ERROR_SYS_ERROR);
|
||||
LOG_ERROR("cannot write to json file '%s': '%s'", tmp, TRI_LAST_ERROR_STR);
|
||||
TRI_UnlinkFile(tmp);
|
||||
|
@ -912,14 +914,14 @@ bool TRI_SaveJson (char const* filename, TRI_json_t const* object) {
|
|||
return false;
|
||||
}
|
||||
|
||||
ok = TRI_fsync(fd);
|
||||
|
||||
if (! ok) {
|
||||
TRI_set_errno(TRI_ERROR_SYS_ERROR);
|
||||
LOG_ERROR("cannot sync saved json '%s': '%s'", tmp, TRI_LAST_ERROR_STR);
|
||||
TRI_UnlinkFile(tmp);
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
|
||||
return false;
|
||||
if (syncFile) {
|
||||
if (! TRI_fsync(fd)) {
|
||||
TRI_set_errno(TRI_ERROR_SYS_ERROR);
|
||||
LOG_ERROR("cannot sync saved json '%s': '%s'", tmp, TRI_LAST_ERROR_STR);
|
||||
TRI_UnlinkFile(tmp);
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
res = TRI_CLOSE(fd);
|
||||
|
@ -935,15 +937,17 @@ bool TRI_SaveJson (char const* filename, TRI_json_t const* object) {
|
|||
res = TRI_RenameFile(tmp, filename);
|
||||
|
||||
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);
|
||||
TRI_UnlinkFile(tmp);
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
|
||||
|
||||
return res;
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -126,6 +126,10 @@
|
|||
#define TRI_HAVE_GETLINE 1
|
||||
#endif
|
||||
|
||||
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
|
||||
#define TRI_HAVE_GETLINE 1
|
||||
#endif
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
#define TRI_SIZEOF_SIZE_T 8
|
||||
#define TRI_ALIGNOF_VOIDP 8
|
||||
|
|
|
@ -414,12 +414,20 @@ static TRI_json_t* ParseObject (yyscan_t scanner, int c) {
|
|||
case STRING_CONSTANT: {
|
||||
char* ptr;
|
||||
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";
|
||||
return NULL;
|
||||
if (ptr == NULL) {
|
||||
yyextra._message = "out-of-memory";
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
array->Set(v8::String::New(name), sub);
|
||||
array->Set(v8::String::New(name, outLength), sub);
|
||||
|
||||
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));
|
||||
|
||||
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) {
|
||||
yyextra._message = "out-of-memory";
|
||||
|
|
|
@ -41,6 +41,9 @@ esac
|
|||
TRI_BITS="$tr_BITS"
|
||||
AC_SUBST(TRI_BITS)
|
||||
|
||||
CFLAGS="${CFLAGS} -DTRI_BITS=${TRI_BITS}"
|
||||
CXXFLAGS="${CXXFLAGS} -DTRI_BITS=${TRI_BITS}"
|
||||
|
||||
dnl ----------------------------------------------------------------------------
|
||||
dnl use automake to generate Makfile.in
|
||||
dnl ----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue