1
0
Fork 0

Merge branch 'devel'

This commit is contained in:
Frank Celler 2012-03-23 08:50:33 +01:00
commit a8558a1c67
19 changed files with 1110 additions and 950 deletions

View File

@ -202,6 +202,8 @@ ALIASES += FN{1}="<tt>\1</tt>"
ALIASES += VAR{1}="<tt>\1</tt>"
ALIASES += LIT{1}="<tt>\1</tt>"
ALIASES += CODE{1}="<tt>\1</tt>"
ALIASES += CODE{2}="<tt>\1, \2</tt>"
ALIASES += CODE{3}="<tt>\1, \2, \3</tt>"
ALIASES += CMDOPT{1}="<tt><b>\1</b></tt>"
ALIASES += CA{1}="<var>\1</var>"
ALIASES += CO{1}="<tt>\1</tt>"

View File

@ -368,10 +368,8 @@ HashIndex* HashIndex_new() {
int HashIndex_add(HashIndex* hashIndex, HashIndexElement* element) {
bool result;
result = TRI_InsertElementAssociativeArray(hashIndex->assocArray.uniqueArray, element, false);
if (result) {
return 0;
}
return -1;
return result ? TRI_ERROR_NO_ERROR : TRI_ERROR_AVOCADO_UNIQUE_CONSTRAINT_VIOLATED;
}
@ -413,11 +411,11 @@ int HashIndex_insert(HashIndex* hashIndex, HashIndexElement* element) {
// Removes an entry from the associative array
// ...............................................................................
bool HashIndex_remove(HashIndex* hashIndex, HashIndexElement* element) {
int HashIndex_remove(HashIndex* hashIndex, HashIndexElement* element) {
bool result;
result = TRI_RemoveElementAssociativeArray(hashIndex->assocArray.uniqueArray, element, NULL);
return result;
return result ? TRI_ERROR_NO_ERROR : TRI_ERROR_INTERNAL;
}
@ -426,10 +424,10 @@ bool HashIndex_remove(HashIndex* hashIndex, HashIndexElement* element) {
// then adds the afterElement
// ...............................................................................
bool HashIndex_update(HashIndex* hashIndex, const HashIndexElement* beforeElement,
int HashIndex_update(HashIndex* hashIndex, const HashIndexElement* beforeElement,
const HashIndexElement* afterElement) {
assert(false);
return false;
return TRI_ERROR_INTERNAL;
}
//------------------------------------------------------------------------------
@ -640,10 +638,10 @@ int MultiHashIndex_insert(HashIndex* hashIndex, HashIndexElement* element) {
// Removes an entry from the associative array
// ...............................................................................
bool MultiHashIndex_remove(HashIndex* hashIndex, HashIndexElement* element) {
int MultiHashIndex_remove(HashIndex* hashIndex, HashIndexElement* element) {
bool result;
result = TRI_RemoveElementMultiArray(hashIndex->assocArray.nonUniqueArray, element, NULL);
return result;
return result ? TRI_ERROR_NO_ERROR : TRI_ERROR_INTERNAL;
}
@ -652,8 +650,8 @@ bool MultiHashIndex_remove(HashIndex* hashIndex, HashIndexElement* element) {
// then adds the afterElement
// ...............................................................................
bool MultiHashIndex_update(HashIndex* hashIndex, HashIndexElement* beforeElement,
int MultiHashIndex_update(HashIndex* hashIndex, HashIndexElement* beforeElement,
HashIndexElement* afterElement) {
assert(false);
return false;
return TRI_ERROR_INTERNAL;
}

View File

@ -35,6 +35,9 @@
/// @author Copyright 2011, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRI_HASH_INDEX_H
#define TRI_HASH_INDEX_H 1
#include <BasicsC/common.h>
#include <BasicsC/associative.h>
#include <BasicsC/associative-multi.h>
@ -82,9 +85,9 @@ HashIndexElements* HashIndex_find (HashIndex*, HashIndexElement*);
int HashIndex_insert (HashIndex*, HashIndexElement*);
bool HashIndex_remove (HashIndex*, HashIndexElement*);
int HashIndex_remove (HashIndex*, HashIndexElement*);
bool HashIndex_update (HashIndex*, const HashIndexElement*, const HashIndexElement*);
int HashIndex_update (HashIndex*, const HashIndexElement*, const HashIndexElement*);
//------------------------------------------------------------------------------
@ -102,6 +105,8 @@ HashIndexElements* MultiHashIndex_find (HashIndex*, HashIndexElement*);
int MultiHashIndex_insert (HashIndex*, HashIndexElement*);
bool MultiHashIndex_remove (HashIndex*, HashIndexElement*);
int MultiHashIndex_remove (HashIndex*, HashIndexElement*);
bool MultiHashIndex_update (HashIndex*, HashIndexElement*, HashIndexElement*);
int MultiHashIndex_update (HashIndex*, HashIndexElement*, HashIndexElement*);
#endif

View File

@ -316,7 +316,7 @@ void AvocadoServer::buildApplicationServer () {
map<string, ProgramOptionsDescription> additional;
additional[ApplicationServer::OPTIONS_CMDLINE]
("shell", "do not start as server, start in shell mode instead")
("console", "do not start as server, start an emergency console instead")
;
additional[ApplicationServer::OPTIONS_CMDLINE + ":help-extended"]
@ -459,7 +459,7 @@ void AvocadoServer::buildApplicationServer () {
// in shell mode ignore the rest
// .............................................................................
if (_applicationServer->programOptions().has("shell")) {
if (_applicationServer->programOptions().has("console")) {
executeShell();
exit(EXIT_SUCCESS);
}

View File

@ -46,7 +46,8 @@
/// @page GlossaryDocument
///
/// @GE{Document}: Documents in AvocadoDB are JSON objects. These objects can be
/// nested (to any depth) and may contains lists.
/// nested (to any depth) and may contains lists. Each document is unique identified
/// by its document handle.
///
/// @page GlossaryDocumentHandle
///

View File

@ -86,9 +86,14 @@
/////////////////////////////////////////////////////////////////
///
/// All documents in AvocadoDB have a document handle. This handle uniquely
/// defines a document and is managed by AvocadoDB. Assume that the document
/// handle, which is stored in the @LIT{_id} field of the document, is
/// @LIT{7254820/362549736}, then the HTTP URI of that document is:
/// defines a document and is managed by AvocadoDB. All documents are
/// found under the URI
///
/// @LIT{document/@FA{document-handle}}
///
/// For exmaple: Assume that the document handle, which is stored in
/// the @LIT{_id} field of the document, is @LIT{7254820/362549736},
/// then the URL of that document is:
///
/// @LIT{http://localhost:8529/document/7254820/362549736}
///

View File

@ -2025,7 +2025,7 @@ static v8::Handle<v8::Value> JS_SkiplistSelectAql (v8::Arguments const& argv) {
if (idx == NULL) {
return scope.Close(v8::ThrowException(v8::String::New("invalid index in where statement")));
}
if (! CheckWhereSkiplistOperators(idx->_shapeList->_length, slWhere->_operator)) {
if (! CheckWhereSkiplistOperators(idx->_paths._length, slWhere->_operator)) {
return scope.Close(v8::ThrowException(v8::String::New("One or more operators has invalid number of attributes")));
}

View File

@ -50,6 +50,7 @@ static bool CreateJournal (TRI_blob_collection_t* collection) {
TRI_datafile_t* journal;
TRI_df_marker_t* position;
bool ok;
int res;
char* filename;
char* jname;
char* number;
@ -95,9 +96,9 @@ static bool CreateJournal (TRI_blob_collection_t* collection) {
TRI_FreeString(filename);
// create a collection header
ok = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position);
res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position);
if (! ok) {
if (res != TRI_ERROR_NO_ERROR) {
TRI_FreeDatafile(journal);
LOG_ERROR("cannot create document header in journal '%s': %s",
@ -117,9 +118,10 @@ static bool CreateJournal (TRI_blob_collection_t* collection) {
cm._cid = collection->base._cid;
TRI_FillCrcMarkerDatafile(&cm.base, sizeof(cm), 0, 0);
ok = TRI_WriteElementDatafile(journal, position, &cm.base, sizeof(cm), 0, 0, true);
if (! ok) {
res = TRI_WriteElementDatafile(journal, position, &cm.base, sizeof(cm), 0, 0, true);
if (res != TRI_ERROR_NO_ERROR) {
TRI_FreeDatafile(journal);
LOG_ERROR("cannot create document header in journal '%s': %s",
@ -202,6 +204,7 @@ static TRI_datafile_t* SelectJournal (TRI_blob_collection_t* collection,
TRI_df_marker_t** result) {
TRI_datafile_t* datafile;
bool ok;
int res;
size_t n;
// need to create a new journal?
@ -220,9 +223,9 @@ static TRI_datafile_t* SelectJournal (TRI_blob_collection_t* collection,
datafile = collection->base._journals._buffer[0];
// try to reserve space
ok = TRI_ReserveElementDatafile(datafile, size, result);
res = TRI_ReserveElementDatafile(datafile, size, result);
while (! ok && TRI_errno() == TRI_ERROR_AVOCADO_DATAFILE_FULL) {
while (res == TRI_ERROR_AVOCADO_DATAFILE_FULL) {
ok = CloseJournal(collection, datafile);
if (! ok) {
@ -238,10 +241,10 @@ static TRI_datafile_t* SelectJournal (TRI_blob_collection_t* collection,
datafile = collection->base._journals._buffer[0];
ok = TRI_ReserveElementDatafile(datafile, size, result);
res = TRI_ReserveElementDatafile(datafile, size, result);
}
if (! ok) {
if (res != TRI_ERROR_NO_ERROR) {
collection->base._state = TRI_COL_STATE_WRITE_ERROR;
return NULL;
}
@ -254,22 +257,22 @@ static TRI_datafile_t* SelectJournal (TRI_blob_collection_t* collection,
/// @brief writes an element to a given position
////////////////////////////////////////////////////////////////////////////////
static bool WriteElement (TRI_blob_collection_t* collection,
TRI_datafile_t* journal,
TRI_df_marker_t* position,
TRI_df_marker_t* marker,
TRI_voc_size_t markerSize,
static int WriteElement (TRI_blob_collection_t* collection,
TRI_datafile_t* journal,
TRI_df_marker_t* position,
TRI_df_marker_t* marker,
TRI_voc_size_t markerSize,
void const* body,
size_t bodySize) {
bool ok;
size_t bodySize) {
int res;
ok = TRI_WriteElementDatafile(journal, position, marker, markerSize, body, bodySize, true);
res = TRI_WriteElementDatafile(journal, position, marker, markerSize, body, bodySize, true);
if (! ok) {
if (res != TRI_ERROR_NO_ERROR) {
collection->base._state = TRI_COL_STATE_WRITE_ERROR;
}
return ok;
return res;
}
////////////////////////////////////////////////////////////////////////////////
@ -357,14 +360,14 @@ void TRI_FreeBlobCollection (TRI_blob_collection_t* collection) {
/// @brief writes an element splitted into marker and body to file
////////////////////////////////////////////////////////////////////////////////
bool TRI_WriteBlobCollection (TRI_blob_collection_t* collection,
TRI_df_marker_t* marker,
TRI_voc_size_t markerSize,
void const* body,
TRI_voc_size_t bodySize,
TRI_df_marker_t** result) {
int TRI_WriteBlobCollection (TRI_blob_collection_t* collection,
TRI_df_marker_t* marker,
TRI_voc_size_t markerSize,
void const* body,
TRI_voc_size_t bodySize,
TRI_df_marker_t** result) {
TRI_datafile_t* journal;
bool ok;
int res;
// generate a new tick
marker->_tick = TRI_NewTickVocBase();
@ -394,12 +397,12 @@ bool TRI_WriteBlobCollection (TRI_blob_collection_t* collection,
}
// and write marker and blob
ok = WriteElement(collection, journal, *result, marker, markerSize, body, bodySize);
res = WriteElement(collection, journal, *result, marker, markerSize, body, bodySize);
// release lock on collection
TRI_UnlockMutex(&collection->_lock);
return ok;
return res;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -117,12 +117,12 @@ void TRI_FreeBlobCollection (TRI_blob_collection_t* collection);
/// @brief writes an element splitted into marker and body to file
////////////////////////////////////////////////////////////////////////////////
bool TRI_WriteBlobCollection (TRI_blob_collection_t* collection,
TRI_df_marker_t* marker,
TRI_voc_size_t markerSize,
void const* body,
TRI_voc_size_t bodySize,
TRI_df_marker_t** result);
int TRI_WriteBlobCollection (TRI_blob_collection_t* collection,
TRI_df_marker_t* marker,
TRI_voc_size_t markerSize,
void const* body,
TRI_voc_size_t bodySize,
TRI_df_marker_t** result);
////////////////////////////////////////////////////////////////////////////////
/// @brief opens an existing collection

View File

@ -112,10 +112,10 @@ static TRI_datafile_t* SelectCompactor (TRI_sim_collection_t* collection,
/// @brief write document to file
////////////////////////////////////////////////////////////////////////////////
static bool CopyDocument (TRI_sim_collection_t* collection,
TRI_df_marker_t const* marker,
TRI_df_marker_t** result,
TRI_voc_fid_t* fid) {
static int CopyDocument (TRI_sim_collection_t* collection,
TRI_df_marker_t const* marker,
TRI_df_marker_t** result,
TRI_voc_fid_t* fid) {
TRI_datafile_t* journal;
TRI_voc_size_t total;
@ -140,6 +140,10 @@ static bool CopyDocument (TRI_sim_collection_t* collection,
////////////////////////////////////////////////////////////////////////////////
/// @brief callback to delete datafile
///
/// Note that a datafile pointer is never freed. The state of the datafile
/// will be switch to TRI_DF_STATE_CLOSED - but the datafile pointer is
/// still valid.
////////////////////////////////////////////////////////////////////////////////
static void RemoveDatafileCallback (TRI_datafile_t* datafile, void* data) {
@ -189,7 +193,7 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
TRI_doc_mptr_t const* found;
TRI_sim_collection_t* collection;
TRI_voc_fid_t fid;
bool ok;
int res;
union { TRI_doc_mptr_t const* c; TRI_doc_mptr_t* v; } cnv;
collection = data;
@ -226,9 +230,9 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
TRI_ReadUnlockReadWriteLock(&collection->_lock);
// write to compactor files
ok = CopyDocument(collection, marker, &result, &fid);
res = CopyDocument(collection, marker, &result, &fid);
if (! ok) {
if (res != TRI_ERROR_NO_ERROR) {
LOG_FATAL("cannot write compactor file: ", TRI_last_error());
return false;
}
@ -269,9 +273,9 @@ static bool Compactifier (TRI_df_marker_t const* marker, void* data, TRI_datafil
// TODO: remove TRI_doc_deletion_marker_t from file
// write to compactor files
ok = CopyDocument(collection, marker, &result, &fid);
res = CopyDocument(collection, marker, &result, &fid);
if (! ok) {
if (res != TRI_ERROR_NO_ERROR) {
LOG_FATAL("cannot write compactor file: ", TRI_last_error());
return false;
}

View File

@ -340,9 +340,9 @@ TRI_datafile_t* TRI_CreateDatafile (char const* filename, TRI_voc_size_t maximal
TRI_df_header_marker_t header;
TRI_df_marker_t* position;
TRI_voc_tick_t tick;
bool ok;
char zero;
int fd;
int result;
off_t offset;
ssize_t res;
void* data;
@ -355,7 +355,6 @@ TRI_datafile_t* TRI_CreateDatafile (char const* filename, TRI_voc_size_t maximal
TRI_set_errno(TRI_ERROR_AVOCADO_MAXIMAL_SIZE_TOO_SMALL);
LOG_ERROR("cannot create datafile '%s', maximal size '%u' is too small", filename, (unsigned int) maximalSize);
return NULL;
}
@ -366,7 +365,6 @@ TRI_datafile_t* TRI_CreateDatafile (char const* filename, TRI_voc_size_t maximal
TRI_set_errno(TRI_ERROR_SYS_ERROR);
LOG_ERROR("cannot create datafile '%s': '%s'", filename, TRI_last_error());
return NULL;
}
@ -378,7 +376,6 @@ TRI_datafile_t* TRI_CreateDatafile (char const* filename, TRI_voc_size_t maximal
close(fd);
LOG_ERROR("cannot seek in datafile '%s': '%s'", filename, TRI_last_error());
return NULL;
}
@ -390,7 +387,6 @@ TRI_datafile_t* TRI_CreateDatafile (char const* filename, TRI_voc_size_t maximal
close(fd);
LOG_ERROR("cannot create sparse datafile '%s': '%s'", filename, TRI_last_error());
return NULL;
}
@ -402,7 +398,6 @@ TRI_datafile_t* TRI_CreateDatafile (char const* filename, TRI_voc_size_t maximal
close(fd);
LOG_ERROR("cannot memory map file '%s': '%s'", filename, TRI_last_error());
return NULL;
}
@ -411,8 +406,13 @@ TRI_datafile_t* TRI_CreateDatafile (char const* filename, TRI_voc_size_t maximal
// create datafile structure
datafile = TRI_Allocate(sizeof(TRI_datafile_t));
if (!datafile) {
// TODO: FIXME
if (datafile == NULL) {
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
close(fd);
LOG_ERROR("out-of-memory");
return NULL;
}
InitDatafile(datafile,
@ -440,13 +440,13 @@ TRI_datafile_t* TRI_CreateDatafile (char const* filename, TRI_voc_size_t maximal
TRI_FillCrcMarkerDatafile(&header.base, sizeof(TRI_df_header_marker_t), 0, 0);
// reserve space and write header to file
ok = TRI_ReserveElementDatafile(datafile, header.base._size, &position);
result = TRI_ReserveElementDatafile(datafile, header.base._size, &position);
if (ok) {
ok = TRI_WriteElementDatafile(datafile, position, &header.base, header.base._size, 0, 0, true);
if (result == TRI_ERROR_NO_ERROR) {
result = TRI_WriteElementDatafile(datafile, position, &header.base, header.base._size, 0, 0, true);
}
if (! ok) {
if (result != TRI_ERROR_NO_ERROR) {
LOG_ERROR("cannot write header to datafile '%s'",
filename);
@ -555,23 +555,20 @@ void TRI_FillCrcMarkerDatafile (TRI_df_marker_t* marker,
/// @brief reserves room for an element, advances the pointer
////////////////////////////////////////////////////////////////////////////////
bool TRI_ReserveElementDatafile (TRI_datafile_t* datafile,
TRI_voc_size_t size,
TRI_df_marker_t** position) {
int TRI_ReserveElementDatafile (TRI_datafile_t* datafile,
TRI_voc_size_t size,
TRI_df_marker_t** position) {
*position = 0;
size = ((size + TRI_DF_BLOCK_ALIGN - 1) / TRI_DF_BLOCK_ALIGN) * TRI_DF_BLOCK_ALIGN;
if (datafile->_state != TRI_DF_STATE_WRITE) {
if (datafile->_state == TRI_DF_STATE_READ) {
TRI_set_errno(TRI_ERROR_AVOCADO_READ_ONLY);
LOG_ERROR("cannot reserve marker, datafile is read-only");
return false;
return TRI_set_errno(TRI_ERROR_AVOCADO_READ_ONLY);
}
TRI_set_errno(TRI_ERROR_AVOCADO_ILLEGAL_STATE);
return false;
return TRI_set_errno(TRI_ERROR_AVOCADO_ILLEGAL_STATE);
}
// add the marker, leave enough room for the footer
@ -581,7 +578,7 @@ bool TRI_ReserveElementDatafile (TRI_datafile_t* datafile,
LOG_TRACE("cannot write marker, not enough space");
return false;
return datafile->_lastError;
}
*position = (TRI_df_marker_t*) datafile->_next;
@ -589,20 +586,20 @@ bool TRI_ReserveElementDatafile (TRI_datafile_t* datafile,
datafile->_next += size;
datafile->_currentSize += size;
return true;
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief writes a marker and body to the datafile
////////////////////////////////////////////////////////////////////////////////
bool TRI_WriteElementDatafile (TRI_datafile_t* datafile,
void* position,
TRI_df_marker_t const* marker,
TRI_voc_size_t markerSize,
void const* body,
TRI_voc_size_t bodySize,
bool forceSync) {
int TRI_WriteElementDatafile (TRI_datafile_t* datafile,
void* position,
TRI_df_marker_t const* marker,
TRI_voc_size_t markerSize,
void const* body,
TRI_voc_size_t bodySize,
bool forceSync) {
TRI_voc_size_t size;
size = markerSize + bodySize;
@ -615,15 +612,12 @@ bool TRI_WriteElementDatafile (TRI_datafile_t* datafile,
if (datafile->_state != TRI_DF_STATE_WRITE) {
if (datafile->_state == TRI_DF_STATE_READ) {
TRI_set_errno(TRI_ERROR_AVOCADO_READ_ONLY);
LOG_ERROR("cannot write marker, datafile is read-only");
return false;
return TRI_set_errno(TRI_ERROR_AVOCADO_READ_ONLY);
}
TRI_set_errno(TRI_ERROR_AVOCADO_ILLEGAL_STATE);
return false;
return TRI_set_errno(TRI_ERROR_AVOCADO_ILLEGAL_STATE);
}
memcpy(position, marker, markerSize);
@ -649,14 +643,14 @@ bool TRI_WriteElementDatafile (TRI_datafile_t* datafile,
LOG_ERROR("msync failed with: %s", TRI_last_error());
return false;
return datafile->_lastError;
}
else {
LOG_TRACE("msync succeeded %p, size %lu", position, (unsigned long) size);
}
}
return true;
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
@ -849,6 +843,7 @@ bool TRI_SealDatafile (TRI_datafile_t* datafile) {
TRI_df_footer_marker_t footer;
TRI_df_marker_t* position;
bool ok;
int res;
if (datafile->_state == TRI_DF_STATE_READ) {
TRI_set_errno(TRI_ERROR_AVOCADO_READ_ONLY);
@ -877,13 +872,14 @@ bool TRI_SealDatafile (TRI_datafile_t* datafile) {
// reserve space and write footer to file
datafile->_footerSize = 0;
ok = TRI_ReserveElementDatafile(datafile, footer.base._size, &position);
if (ok) {
ok = TRI_WriteElementDatafile(datafile, position, &footer.base, footer.base._size, 0, 0, true);
res = TRI_ReserveElementDatafile(datafile, footer.base._size, &position);
if (res == TRI_ERROR_NO_ERROR) {
res = TRI_WriteElementDatafile(datafile, position, &footer.base, footer.base._size, 0, 0, true);
}
if (! ok) {
if (res != TRI_ERROR_NO_ERROR) {
return false;
}
@ -912,8 +908,6 @@ bool TRI_SealDatafile (TRI_datafile_t* datafile) {
// truncate datafile
if (ok) {
int res;
res = ftruncate(datafile->_fd, datafile->_currentSize);
if (res < 0) {
@ -925,7 +919,7 @@ bool TRI_SealDatafile (TRI_datafile_t* datafile) {
datafile->_state = TRI_DF_STATE_READ;
}
return ok;
return ok ? TRI_ERROR_NO_ERROR : datafile->_lastError;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -431,15 +431,15 @@ void TRI_FillCrcMarkerDatafile (TRI_df_marker_t* marker,
/// @brief reserves room for an element, advances the pointer
////////////////////////////////////////////////////////////////////////////////
bool TRI_ReserveElementDatafile (TRI_datafile_t* datafile,
TRI_voc_size_t size,
TRI_df_marker_t** position);
int TRI_ReserveElementDatafile (TRI_datafile_t* datafile,
TRI_voc_size_t size,
TRI_df_marker_t** position);
////////////////////////////////////////////////////////////////////////////////
/// @brief writes a marker and body to the datafile
////////////////////////////////////////////////////////////////////////////////
bool TRI_WriteElementDatafile (TRI_datafile_t*,
int TRI_WriteElementDatafile (TRI_datafile_t*,
void* position,
TRI_df_marker_t const* marker,
TRI_voc_size_t markerSize,

View File

@ -212,6 +212,7 @@ TRI_datafile_t* CreateJournalDocCollection (TRI_doc_collection_t* collection, bo
TRI_datafile_t* journal;
TRI_df_marker_t* position;
bool ok;
int res;
char* filename;
char* jname;
char* number;
@ -288,9 +289,9 @@ TRI_datafile_t* CreateJournalDocCollection (TRI_doc_collection_t* collection, bo
TRI_FreeString(filename);
// create a collection header
ok = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position);
res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position);
if (! ok) {
if (res != TRI_ERROR_NO_ERROR) {
collection->base._lastError = journal->_lastError;
TRI_FreeDatafile(journal);
@ -308,9 +309,10 @@ TRI_datafile_t* CreateJournalDocCollection (TRI_doc_collection_t* collection, bo
cm._cid = collection->base._cid;
TRI_FillCrcMarkerDatafile(&cm.base, sizeof(cm), 0, 0);
ok = TRI_WriteElementDatafile(journal, position, &cm.base, sizeof(cm), 0, 0, true);
if (! ok) {
res = TRI_WriteElementDatafile(journal, position, &cm.base, sizeof(cm), 0, 0, true);
if (res != TRI_ERROR_NO_ERROR) {
collection->base._lastError = journal->_lastError;
TRI_FreeDatafile(journal);

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
///
/// DISCLAIMER
///
/// Copyright 2010-2011 triagens GmbH, Cologne, Germany
/// Copyright 2011-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.
@ -22,7 +22,7 @@
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2011, triAGENS GmbH, Cologne, Germany
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_DURHAM_VOC_BASE_INDEX_H
@ -89,19 +89,6 @@ typedef enum {
}
TRI_index_geo_variant_e;
////////////////////////////////////////////////////////////////////////////////
/// @brief index definition struct as used by the query optimizer
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_index_definition_s {
TRI_idx_iid_t _iid;
TRI_idx_type_e _type;
TRI_vector_string_t* _fields;
bool _isUnique;
TRI_index_geo_variant_e _geoVariant;
}
TRI_index_definition_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief index base class
////////////////////////////////////////////////////////////////////////////////
@ -111,9 +98,12 @@ typedef struct TRI_index_s {
TRI_idx_type_e _type;
struct TRI_doc_collection_s* _collection;
bool (*insert) (struct TRI_index_s*, struct TRI_doc_mptr_s const*);
bool (*remove) (struct TRI_index_s*, struct TRI_doc_mptr_s const*);
bool (*update) (struct TRI_index_s*, struct TRI_doc_mptr_s const*, struct TRI_shaped_json_s const*);
bool _unique;
TRI_vector_string_t _fields;
int (*insert) (struct TRI_index_s*, struct TRI_doc_mptr_s const*);
int (*remove) (struct TRI_index_s*, struct TRI_doc_mptr_s const*);
int (*update) (struct TRI_index_s*, struct TRI_doc_mptr_s const*, struct TRI_shaped_json_s const*);
TRI_json_t* (*json) (struct TRI_index_s*, struct TRI_doc_collection_s*);
}
TRI_index_t;
@ -124,6 +114,7 @@ TRI_index_t;
typedef struct TRI_geo_index_s {
TRI_index_t base;
TRI_index_geo_variant_e _variant;
GeoIndex* _geoIndex;
@ -135,7 +126,6 @@ typedef struct TRI_geo_index_s {
}
TRI_geo_index_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief hash index
////////////////////////////////////////////////////////////////////////////////
@ -143,11 +133,10 @@ TRI_geo_index_t;
typedef struct TRI_hash_index_s {
TRI_index_t base;
HashIndex* _hashIndex; // effectively the associative array
TRI_vector_t* _shapeList; // a list of shape pid which identifies the fields of the index
bool _unique;
} TRI_hash_index_t;
HashIndex* _hashIndex; // effectively the associative array
TRI_vector_t _paths; // a list of shape pid which identifies the fields of the index
}
TRI_hash_index_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief skiplist index
@ -156,10 +145,10 @@ typedef struct TRI_hash_index_s {
typedef struct TRI_skiplist_index_s {
TRI_index_t base;
SkiplistIndex* _skiplistIndex; // effectively the skiplist
TRI_vector_t* _shapeList; // a list of shape pid which identifies the fields of the index
bool _unique;
} TRI_skiplist_index_t;
SkiplistIndex* _skiplistIndex; // effectively the skiplist
TRI_vector_t _paths; // a list of shape pid which identifies the fields of the index
}
TRI_skiplist_index_t;
////////////////////////////////////////////////////////////////////////////////
/// @}
@ -182,7 +171,7 @@ typedef struct TRI_skiplist_index_s {
/// @brief removes an index file
////////////////////////////////////////////////////////////////////////////////
bool TRI_RemoveIndex (struct TRI_doc_collection_s* collection, TRI_index_t* idx);
bool TRI_RemoveIndexFile (struct TRI_doc_collection_s* collection, TRI_index_t* idx);
////////////////////////////////////////////////////////////////////////////////
/// @brief saves an index
@ -196,37 +185,11 @@ bool TRI_SaveIndex (struct TRI_doc_collection_s*, TRI_index_t*);
TRI_index_t* TRI_LookupIndex (struct TRI_doc_collection_s*, TRI_idx_iid_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief free an existing index definition
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeIndexDefinition (TRI_index_definition_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief free an existing index definitions vector
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeIndexDefinitions (TRI_vector_pointer_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief gets name of index type
////////////////////////////////////////////////////////////////////////////////
char* TRI_GetTypeNameIndex (const TRI_index_definition_t* const);
////////////////////////////////////////////////////////////////////////////////
/// @brief gets the definitions of all index files for a collection
////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t* TRI_GetCollectionIndexes (const TRI_vocbase_t* vocbase,
const char* collectionName);
////////////////////////////////////////////////////////////////////////////////
/// @brief gets the names of all index files for a collection
////////////////////////////////////////////////////////////////////////////////
TRI_vector_string_t TRI_GetCollectionIndexFiles (const TRI_vocbase_t* vocbase,
const char* collectionName);
char const* TRI_TypeNameIndex (const TRI_index_t* const);
////////////////////////////////////////////////////////////////////////////////
/// @}
@ -254,6 +217,7 @@ TRI_vector_string_t TRI_GetCollectionIndexFiles (const TRI_vocbase_t* vocbase,
////////////////////////////////////////////////////////////////////////////////
TRI_index_t* TRI_CreateGeoIndex (struct TRI_doc_collection_s*,
char const* locationName,
TRI_shape_pid_t,
bool geoJson);
@ -262,7 +226,9 @@ TRI_index_t* TRI_CreateGeoIndex (struct TRI_doc_collection_s*,
////////////////////////////////////////////////////////////////////////////////
TRI_index_t* TRI_CreateGeoIndex2 (struct TRI_doc_collection_s*,
char const* latitudeName,
TRI_shape_pid_t,
char const* longitudeName,
TRI_shape_pid_t);
////////////////////////////////////////////////////////////////////////////////
@ -333,7 +299,8 @@ GeoCoordinates* TRI_NearestGeoIndex (TRI_index_t*,
////////////////////////////////////////////////////////////////////////////////
TRI_index_t* TRI_CreateHashIndex (struct TRI_doc_collection_s*,
TRI_vector_t* shapeList,
TRI_vector_pointer_t* fields,
TRI_vector_t* paths,
bool unique);
////////////////////////////////////////////////////////////////////////////////
@ -392,7 +359,8 @@ TRI_skiplist_iterator_t* TRI_LookupSkiplistIndex (TRI_index_t*, TRI_sl_operator_
////////////////////////////////////////////////////////////////////////////////
TRI_index_t* TRI_CreateSkiplistIndex (struct TRI_doc_collection_s*,
TRI_vector_t* shapeList,
TRI_vector_pointer_t* fields,
TRI_vector_t* paths,
bool unique);

View File

@ -25,10 +25,11 @@
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include <BasicsC/logging.h>
#include <BasicsC/string-buffer.h>
#include "query-join-execute.h"
#include "VocBase/query-join-execute.h"
#include "BasicsC/logging.h"
#include "BasicsC/string-buffer.h"
#include "BasicsC/strings.h"
#include "VocBase/query-join.h"
////////////////////////////////////////////////////////////////////////////////
@ -40,25 +41,25 @@
/// @brief log information about the used index
////////////////////////////////////////////////////////////////////////////////
static void LogIndexString(const TRI_index_definition_t* const indexDefinition,
const char* const collectionName) {
static void LogIndexString(TRI_index_t const* idx,
char const* collectionName) {
TRI_string_buffer_t* buffer = TRI_CreateStringBuffer();
size_t i;
if (!buffer) {
if (buffer == NULL) {
return;
}
for (i = 0; i < indexDefinition->_fields->_length; i++) {
for (i = 0; i < idx->_fields._length; i++) {
if (i > 0) {
TRI_AppendStringStringBuffer(buffer, ", ");
}
TRI_AppendStringStringBuffer(buffer, indexDefinition->_fields->_buffer[i]);
TRI_AppendStringStringBuffer(buffer, idx->_fields._buffer[i]);
}
LOG_DEBUG("using %s index (%s) for '%s'",
TRI_GetTypeNameIndex(indexDefinition),
TRI_TypeNameIndex(idx),
buffer->_buffer,
collectionName);
@ -74,6 +75,9 @@ static TRI_data_feeder_t* DetermineGeoIndexUsageX (const TRI_vocbase_t* vocbase,
const TRI_select_join_t* join,
const size_t level,
const TRI_join_part_t* part) {
assert(false);
#if 0
TRI_vector_pointer_t* indexDefinitions;
TRI_index_definition_t* indexDefinition;
TRI_data_feeder_t* feeder = NULL;
@ -125,6 +129,7 @@ static TRI_data_feeder_t* DetermineGeoIndexUsageX (const TRI_vocbase_t* vocbase,
TRI_FreeIndexDefinitions(indexDefinitions);
return feeder;
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -135,6 +140,9 @@ static TRI_data_feeder_t* DetermineIndexUsageX (const TRI_vocbase_t* vocbase,
const TRI_select_join_t* join,
const size_t level,
const TRI_join_part_t* part) {
assert(false);
#if 0
TRI_vector_pointer_t* indexDefinitions;
TRI_index_definition_t* indexDefinition;
TRI_data_feeder_t* feeder = NULL;
@ -310,50 +318,51 @@ EXIT2:
}
return feeder;
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Determine which geo indexes to use in a query
/// @brief determines which geo indexes to use in a query
////////////////////////////////////////////////////////////////////////////////
static TRI_data_feeder_t* DetermineGeoIndexUsage (TRI_query_instance_t* const instance,
const size_t level,
const TRI_join_part_t* part) {
TRI_vector_pointer_t* indexDefinitions;
TRI_vector_pointer_t* indexes;
TRI_data_feeder_t* feeder = NULL;
size_t i;
assert(part->_geoRestriction);
indexDefinitions = TRI_GetCollectionIndexes(instance->_template->_vocbase,
part->_collectionName);
if (!indexDefinitions) {
TRI_RegisterErrorQueryInstance(instance, TRI_ERROR_OUT_OF_MEMORY, NULL);
if (part->_collection->base._type != TRI_COL_TYPE_SIMPLE_DOCUMENT) {
TRI_RegisterErrorQueryInstance(instance,
TRI_ERROR_AVOCADO_UNKNOWN_COLLECTION_TYPE,
part->_alias);
return NULL;
}
indexes = & ((TRI_sim_collection_t*) part->_collection)->_indexes;
// enum all indexes
for (i = 0; i < indexDefinitions->_length; i++) {
TRI_index_definition_t* indexDefinition;
for (i = 0; i < indexes->_length; i++) {
TRI_index_t* idx;
indexDefinition = (TRI_index_definition_t*) indexDefinitions->_buffer[i];
idx = (TRI_index_t*) indexes->_buffer[i];
if (indexDefinition->_type != TRI_IDX_TYPE_GEO_INDEX) {
if (idx->_type != TRI_IDX_TYPE_GEO_INDEX) {
// ignore all indexes except geo indexes here
continue;
}
if (indexDefinition->_fields->_length != 2) {
if (idx->_fields._length != 2) {
continue;
}
if (strcmp(indexDefinition->_fields->_buffer[0],
part->_geoRestriction->_compareLat._field) != 0) {
if (! TRI_EqualString(idx->_fields._buffer[0], part->_geoRestriction->_compareLat._field)) {
continue;
}
if (strcmp(indexDefinition->_fields->_buffer[1],
part->_geoRestriction->_compareLon._field) != 0) {
if (! TRI_EqualString(idx->_fields._buffer[1], part->_geoRestriction->_compareLon._field)) {
continue;
}
@ -361,16 +370,14 @@ static TRI_data_feeder_t* DetermineGeoIndexUsage (TRI_query_instance_t* const in
TRI_CreateDataFeederGeoLookup(instance,
(TRI_doc_collection_t*) part->_collection,
level,
indexDefinition->_iid,
idx->_iid,
part->_geoRestriction);
LogIndexString(indexDefinition, part->_alias);
LogIndexString(idx, part->_alias);
break;
}
TRI_FreeIndexDefinitions(indexDefinitions);
if (!feeder) {
if (feeder == NULL) {
TRI_RegisterErrorQueryInstance(instance,
TRI_ERROR_QUERY_GEO_INDEX_MISSING,
part->_alias);
@ -386,7 +393,7 @@ static TRI_data_feeder_t* DetermineGeoIndexUsage (TRI_query_instance_t* const in
static TRI_data_feeder_t* DetermineIndexUsage (TRI_query_instance_t* const instance,
const size_t level,
const TRI_join_part_t* part) {
TRI_vector_pointer_t* indexDefinitions;
TRI_vector_pointer_t* indexes;
TRI_data_feeder_t* feeder = NULL;
size_t i;
@ -400,21 +407,24 @@ static TRI_data_feeder_t* DetermineIndexUsage (TRI_query_instance_t* const insta
size_t numConsts;
TRI_InitVectorPointer(&matches);
indexDefinitions = TRI_GetCollectionIndexes(instance->_template->_vocbase,
part->_collectionName);
if (!indexDefinitions) {
TRI_RegisterErrorQueryInstance(instance, TRI_ERROR_OUT_OF_MEMORY, NULL);
goto EXIT2;
if (part->_collection->base._type != TRI_COL_TYPE_SIMPLE_DOCUMENT) {
TRI_RegisterErrorQueryInstance(instance,
TRI_ERROR_AVOCADO_UNKNOWN_COLLECTION_TYPE,
part->_alias);
return NULL;
}
indexes = & ((TRI_sim_collection_t*) part->_collection)->_indexes;
// enum all indexes
for (i = 0; i < indexDefinitions->_length; i++) {
TRI_index_definition_t* indexDefinition;
for (i = 0; i < indexes->_length; i++) {
TRI_index_t* idx;
size_t j;
indexDefinition = (TRI_index_definition_t*) indexDefinitions->_buffer[i];
if (indexDefinition->_type == TRI_IDX_TYPE_GEO_INDEX) {
idx = (TRI_index_t*) indexes->_buffer[i];
if (idx->_type == TRI_IDX_TYPE_GEO_INDEX) {
// ignore all geo indexes here
continue;
}
@ -424,11 +434,13 @@ static TRI_data_feeder_t* DetermineIndexUsage (TRI_query_instance_t* const insta
TRI_DestroyVectorPointer(&matches);
TRI_InitVectorPointer(&matches);
}
numFields = 0;
numConsts = 0;
numFieldsDefined = indexDefinition->_fields->_length;
for (j = 0 ; j < numFieldsDefined; j++) {
numFieldsDefined = idx->_fields._length;
for (j = 0; j < numFieldsDefined; j++) {
size_t k;
// enumerate all fields from the index definition and
@ -437,6 +449,7 @@ static TRI_data_feeder_t* DetermineIndexUsage (TRI_query_instance_t* const insta
QL_optimize_range_t* range;
range = (QL_optimize_range_t*) part->_ranges->_buffer[k];
if (!range) {
continue;
}
@ -446,18 +459,17 @@ static TRI_data_feeder_t* DetermineIndexUsage (TRI_query_instance_t* const insta
assert(part->_alias);
// check if collection name matches
if (strcmp(range->_collection, part->_alias) != 0) {
if (! TRI_EqualString(range->_collection, part->_alias)) {
continue;
}
// check if field names match
if (strcmp(indexDefinition->_fields->_buffer[j],
range->_field) != 0) {
if (! TRI_EqualString(idx->_fields._buffer[j], range->_field)) {
continue;
}
if (indexDefinition->_type == TRI_IDX_TYPE_PRIMARY_INDEX ||
indexDefinition->_type == TRI_IDX_TYPE_HASH_INDEX) {
if (idx->_type == TRI_IDX_TYPE_PRIMARY_INDEX ||
idx->_type == TRI_IDX_TYPE_HASH_INDEX) {
// check if index can be used
// (primary and hash index only support equality comparisons)
if (range->_minStatus == RANGE_VALUE_INFINITE ||
@ -504,7 +516,7 @@ static TRI_data_feeder_t* DetermineIndexUsage (TRI_query_instance_t* const insta
// we have found as many matches as defined in the index definition
// that means the index is fully covered in the condition
if (indexDefinition->_type == TRI_IDX_TYPE_PRIMARY_INDEX) {
if (idx->_type == TRI_IDX_TYPE_PRIMARY_INDEX) {
// use the collection's primary index
if (feeder) {
// free any other feeder previously set up
@ -519,7 +531,7 @@ static TRI_data_feeder_t* DetermineIndexUsage (TRI_query_instance_t* const insta
if (feeder) {
// we always exit if we can use the primary index
// the primary index guarantees uniqueness
LogIndexString(indexDefinition, part->_alias);
LogIndexString(idx, part->_alias);
goto EXIT;
}
}
@ -528,33 +540,33 @@ static TRI_data_feeder_t* DetermineIndexUsage (TRI_query_instance_t* const insta
// if the index found contains more fields than the one we previously found,
// we use the new one
// (assumption: the more fields index, the less selective is the index)
if (indexDefinition->_type == TRI_IDX_TYPE_HASH_INDEX ||
indexDefinition->_type == TRI_IDX_TYPE_SKIPLIST_INDEX) {
if (idx->_type == TRI_IDX_TYPE_HASH_INDEX ||
idx->_type == TRI_IDX_TYPE_SKIPLIST_INDEX) {
// use a hash index defined for the collection
if (feeder) {
// free any other feeder previously set up
feeder->free(feeder);
}
if (indexDefinition->_type == TRI_IDX_TYPE_SKIPLIST_INDEX) {
if (idx->_type == TRI_IDX_TYPE_SKIPLIST_INDEX) {
feeder =
TRI_CreateDataFeederSkiplistLookup(instance,
(TRI_doc_collection_t*) part->_collection,
level,
indexDefinition->_iid,
idx->_iid,
TRI_CopyVectorPointer(&matches));
LogIndexString(indexDefinition, part->_alias);
LogIndexString(idx, part->_alias);
}
else {
feeder =
TRI_CreateDataFeederHashLookup(instance,
(TRI_doc_collection_t*) part->_collection,
level,
indexDefinition->_iid,
idx->_iid,
TRI_CopyVectorPointer(&matches));
LogIndexString(indexDefinition, part->_alias);
LogIndexString(idx, part->_alias);
}
if (!feeder) {
@ -571,12 +583,9 @@ static TRI_data_feeder_t* DetermineIndexUsage (TRI_query_instance_t* const insta
}
EXIT:
TRI_FreeIndexDefinitions(indexDefinitions);
TRI_DestroyVectorPointer(&matches);
}
EXIT2:
if (!feeder) {
// if no index can be used, we'll do a full table scan
feeder = TRI_CreateDataFeederTableScan(instance,

File diff suppressed because it is too large Load Diff

View File

@ -138,7 +138,7 @@ static bool EqualKeyAttributeName (TRI_associative_synced_t* array, void const*
static TRI_shape_aid_t FindAttributeName (TRI_shaper_t* shaper, char const* name) {
TRI_df_attribute_marker_t marker;
TRI_df_marker_t* result;
bool ok;
int res;
size_t n;
voc_shaper_t* s;
void const* p;
@ -175,9 +175,9 @@ static TRI_shape_aid_t FindAttributeName (TRI_shaper_t* shaper, char const* name
marker._size = n;
// write into the shape collection
ok = TRI_WriteBlobCollection(s->_collection, &marker.base, sizeof(TRI_df_attribute_marker_t), name, n, &result);
res = TRI_WriteBlobCollection(s->_collection, &marker.base, sizeof(TRI_df_attribute_marker_t), name, n, &result);
if (! ok) {
if (res != TRI_ERROR_NO_ERROR) {
TRI_UnlockMutex(&s->_attributeLock);
return 0;
}
@ -283,7 +283,7 @@ static TRI_shape_t const* FindShape (TRI_shaper_t* shaper, TRI_shape_t* shape) {
TRI_df_shape_marker_t marker;
TRI_shape_t const* found;
TRI_shape_t* l;
bool ok;
int res;
voc_shaper_t* s;
void* f;
@ -317,9 +317,9 @@ static TRI_shape_t const* FindShape (TRI_shaper_t* shaper, TRI_shape_t* shape) {
shape->_sid = s->_nextSid++;
// write into the shape collection
ok = TRI_WriteBlobCollection(s->_collection, &marker.base, sizeof(TRI_df_shape_marker_t), shape, shape->_size, &result);
res = TRI_WriteBlobCollection(s->_collection, &marker.base, sizeof(TRI_df_shape_marker_t), shape, shape->_size, &result);
if (! ok) {
if (res != TRI_ERROR_NO_ERROR) {
TRI_UnlockMutex(&s->_shapeLock);
return NULL;
}

View File

@ -196,17 +196,24 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
if (found != NULL) {
TRI_Free(col);
LOG_ERROR("duplicate entry for name '%s'", name);
TRI_set_errno(TRI_ERROR_AVOCADO_DUPLICATE_NAME);
return NULL;
}
// check collection identifier
// check collection identifier (unknown for new born collections)
if (cid != 0) {
found = TRI_InsertKeyAssociativePointer(&vocbase->_collectionsById, &cid, col, false);
if (found != NULL) {
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, name);
TRI_Free(col);
LOG_ERROR("duplicate collection identifier '%lu' for name '%s'", (unsigned long) cid, name);
TRI_set_errno(TRI_ERROR_AVOCADO_DUPLICATE_IDENTIFIER);
return NULL;
}
}
@ -219,7 +226,7 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
/// @brief scans a directory and loads all collections
////////////////////////////////////////////////////////////////////////////////
static void ScanPath (TRI_vocbase_t* vocbase, char const* path) {
static bool ScanPath (TRI_vocbase_t* vocbase, char const* path) {
TRI_vector_string_t files;
TRI_col_type_e type;
size_t n;
@ -239,8 +246,10 @@ static void ScanPath (TRI_vocbase_t* vocbase, char const* path) {
}
file = TRI_Concatenate2File(path, name);
if (!file) {
continue;
if (file == NULL) {
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
return false;
}
if (TRI_IsDirectory(file)) {
@ -256,7 +265,15 @@ static void ScanPath (TRI_vocbase_t* vocbase, char const* path) {
type = info._type;
if (type == TRI_COL_TYPE_SIMPLE_DOCUMENT) {
AddCollection(vocbase, type, info._name, info._cid, file);
TRI_vocbase_col_t* c;
c = AddCollection(vocbase, type, info._name, info._cid, file);
if (c == NULL) {
LOG_FATAL("failed to add simple document collection from '%s'", file);
return false;
}
LOG_DEBUG("added simple document collection from '%s'", file);
}
else {
@ -272,6 +289,7 @@ static void ScanPath (TRI_vocbase_t* vocbase, char const* path) {
}
TRI_DestroyVectorString(&files);
return true;
}
////////////////////////////////////////////////////////////////////////////////
@ -308,6 +326,8 @@ size_t PageSize;
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if a collection is allowed
///
/// Returns 0 for success or the offending character.
////////////////////////////////////////////////////////////////////////////////
char TRI_IsAllowedCollectionName (char const* name) {
@ -414,6 +434,7 @@ TRI_vocbase_t* TRI_OpenVocBase (char const* path) {
TRI_vocbase_t* vocbase;
char* lockFile;
int lockCheck;
bool ok;
if (! TRI_IsDirectory(path)) {
LOG_ERROR("database path '%s' is not a directory", path);
@ -422,9 +443,18 @@ TRI_vocbase_t* TRI_OpenVocBase (char const* path) {
// check if the database is locked
lockFile = TRI_Concatenate2File(path, "lock");
if (lockFile == NULL) {
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
LOG_ERROR("out of memory when opening database");
return NULL;
}
lockCheck = TRI_VerifyLockFile(lockFile);
if (lockCheck) {
TRI_set_errno(TRI_ERROR_AVOCADO_DATABASE_LOCKED);
LOG_FATAL("database is locked, please check the lock file '%s'", lockFile);
TRI_FreeString(lockFile);
return NULL;
@ -439,32 +469,39 @@ TRI_vocbase_t* TRI_OpenVocBase (char const* path) {
if (! lockCheck) {
LOG_FATAL("cannot lock the database, please check the lock file '%s': %s", lockFile, TRI_last_error());
TRI_FreeString(lockFile);
return NULL;
}
// setup vocbase structure
vocbase = TRI_Allocate(sizeof(TRI_vocbase_t));
if (!vocbase) {
LOG_ERROR("out of memory when opening vocbase");
if (vocbase == NULL) {
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
LOG_ERROR("out of memory when opening database");
return NULL;
}
vocbase->_cursors = TRI_CreateShadowsQueryCursor();
if (!vocbase->_cursors) {
if (vocbase->_cursors == NULL) {
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
TRI_FreeShadowStore(vocbase->_cursors);
TRI_Free(vocbase);
LOG_ERROR("out of memory when opening vocbase");
LOG_ERROR("out of memory when opening database");
return NULL;
}
vocbase->_lockFile = lockFile;
vocbase->_path = TRI_DuplicateString(path);
if (!vocbase->_path) {
if (vocbase->_path == NULL) {
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
TRI_FreeShadowStore(vocbase->_cursors);
TRI_Free(vocbase);
LOG_ERROR("out of memory when opening vocbase");
LOG_ERROR("out of memory when opening database");
return NULL;
}
@ -485,7 +522,11 @@ TRI_vocbase_t* TRI_OpenVocBase (char const* path) {
NULL);
// scan directory for collections
ScanPath(vocbase, vocbase->_path);
ok = ScanPath(vocbase, vocbase->_path);
if (! ok) {
return NULL;
}
// vocbase is now active
vocbase->_active = 1;
@ -514,9 +555,8 @@ void TRI_CloseVocBase (TRI_vocbase_t* vocbase) {
TRI_JoinThread(&vocbase->_synchroniser);
TRI_JoinThread(&vocbase->_compactor);
// Free shadows
// cursors
if (vocbase->_cursors) {
// cursors
TRI_FreeShadowStore(vocbase->_cursors);
}
@ -619,6 +659,8 @@ TRI_vocbase_col_t const* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TR
found = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
if (found != NULL) {
TRI_set_errno(TRI_ERROR_AVOCADO_DUPLICATE_NAME);
LOG_ERROR("collection named '%s' already exists", name);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
return NULL;
@ -628,6 +670,8 @@ TRI_vocbase_col_t const* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TR
wrong = TRI_IsAllowedCollectionName(name);
if (wrong != 0) {
TRI_set_errno(TRI_ERROR_AVOCADO_ILLEGAL_NAME);
LOG_ERROR("found illegal character in name: %c", wrong);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
return NULL;
@ -647,6 +691,8 @@ TRI_vocbase_col_t const* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TR
}
}
else {
TRI_set_errno(TRI_ERROR_AVOCADO_UNKNOWN_COLLECTION_TYPE);
LOG_ERROR("unknown collection type: %d", parameter->_type);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
return NULL;
@ -694,6 +740,8 @@ TRI_vocbase_col_t const* TRI_LoadCollectionVocBase (TRI_vocbase_t* vocbase, char
found.c = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name);
if (found.c == NULL) {
TRI_set_errno(TRI_ERROR_AVOCADO_COLLECTION_NOT_FOUND);
LOG_ERROR("unknown collection '%s'", name);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
return NULL;
@ -727,6 +775,8 @@ TRI_vocbase_col_t const* TRI_LoadCollectionVocBase (TRI_vocbase_t* vocbase, char
return found.c;
}
else {
TRI_set_errno(TRI_ERROR_AVOCADO_UNKNOWN_COLLECTION_TYPE);
LOG_ERROR("unknown collection type %d for '%s'", (int) found.c->_type, name);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
return NULL;
@ -754,6 +804,8 @@ TRI_vocbase_col_t const* TRI_BearCollectionVocBase (TRI_vocbase_t* vocbase, char
wrong = TRI_IsAllowedCollectionName(name);
if (wrong != 0) {
TRI_set_errno(TRI_ERROR_AVOCADO_ILLEGAL_NAME);
LOG_ERROR("found illegal character in name: %c", wrong);
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
return NULL;
@ -762,6 +814,11 @@ TRI_vocbase_col_t const* TRI_BearCollectionVocBase (TRI_vocbase_t* vocbase, char
// check if the collection is not already loaded
found.v = AddCollection(vocbase, TRI_COL_TYPE_SIMPLE_DOCUMENT, name, 0, NULL);
if (found.v == NULL) {
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);
return NULL;
}
found.v->_newBorn = 1;
TRI_WriteUnlockReadWriteLock(&vocbase->_lock);