1
0
Fork 0

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

This commit is contained in:
Frank Celler 2013-03-15 11:37:59 +01:00
commit b0fc77d83d
48 changed files with 6243 additions and 95 deletions

View File

@ -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`.

View File

@ -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

View File

@ -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"

View File

@ -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 \

View File

@ -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 {

View File

@ -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);

View File

@ -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 \

View File

@ -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;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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);
} }
} }

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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;
} }

View File

@ -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());

View File

@ -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;

View File

@ -960,7 +960,7 @@ TRI_shaper_t* TRI_CreateVocShaper (TRI_vocbase_t* vocbase,
return NULL; return NULL;
} }
res = TRI_SaveCollectionInfo(collection->base._directory, &parameter); res = TRI_SaveCollectionInfo(collection->base._directory, &parameter, 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);

View File

@ -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) {

View File

@ -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;

View File

@ -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;
} }

View File

@ -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 = "";
}; };

View File

@ -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>

View File

@ -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;
} }

View File

@ -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/";

View File

@ -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();

View File

@ -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) {

View File

@ -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];

View File

@ -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;

View File

@ -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 () {

View File

@ -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;

View File

@ -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');
} }
} }

View File

@ -90,7 +90,7 @@ function CompactionSuite () {
maxWait = 750; maxWait = 750;
} }
else { else {
maxWait = 75; maxWait = 90;
} }
waited = 0; waited = 0;

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @} /// @}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -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 );
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @} /// @}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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";

View File

@ -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 ----------------------------------------------------------------------------