1
0
Fork 0
This commit is contained in:
scottashton 2014-03-21 15:33:08 +01:00
commit 149d90e78b
17 changed files with 545 additions and 334 deletions

View File

@ -1,6 +1,13 @@
v2.1.0 (XXXX-XX-XX) v2.1.0 (XXXX-XX-XX)
------------------- -------------------
* fixed V8 compile error on MacOS X
* prevent `body length: -9223372036854775808` being logged in development mode for
some Foxx HTTP responses
* fixed several bugs in web interface dashboard
* fixed issue #783: coffee script not working in manifest file * fixed issue #783: coffee script not working in manifest file
* provide a size hint to indexes when initially filling them * provide a size hint to indexes when initially filling them

View File

@ -152,6 +152,7 @@ add_executable(
Wal/Configuration.cpp Wal/Configuration.cpp
Wal/LogfileManager.cpp Wal/LogfileManager.cpp
Wal/Logfile.cpp Wal/Logfile.cpp
Wal/Slot.cpp
Wal/Slots.cpp Wal/Slots.cpp
Wal/SynchroniserThread.cpp Wal/SynchroniserThread.cpp
${ARANGOD_MRUBY_SOURCE} ${ARANGOD_MRUBY_SOURCE}

View File

@ -118,6 +118,7 @@ bin_arangod_SOURCES = \
arangod/Wal/Configuration.cpp \ arangod/Wal/Configuration.cpp \
arangod/Wal/LogfileManager.cpp \ arangod/Wal/LogfileManager.cpp \
arangod/Wal/Logfile.cpp \ arangod/Wal/Logfile.cpp \
arangod/Wal/Slot.cpp \
arangod/Wal/Slots.cpp \ arangod/Wal/Slots.cpp \
arangod/Wal/SynchroniserThread.cpp arangod/Wal/SynchroniserThread.cpp

View File

@ -88,8 +88,6 @@ void CollectorThread::stop () {
void CollectorThread::run () { void CollectorThread::run () {
while (_stop == 0) { while (_stop == 0) {
LOG_INFO("hello from collector thread");
Logfile* logfile = _logfileManager->getCollectableLogfile(); Logfile* logfile = _logfileManager->getCollectableLogfile();
if (logfile != nullptr) { if (logfile != nullptr) {

View File

@ -130,7 +130,7 @@ if (i % 500000 == 0) {
LOG_INFO("now at: %d", (int) i); LOG_INFO("now at: %d", (int) i);
} }
memcpy(static_cast<char*>(p) + sizeof(TRI_df_marker_t), "the fox is brown\0", strlen("the fox is brown") + 1); memcpy(static_cast<char*>(p) + sizeof(TRI_df_marker_t), "the fox is brown\0", strlen("the fox is brown") + 1);
_logfileManager->allocateAndWrite(p, static_cast<uint32_t>(64), (int) i); _logfileManager->allocateAndWrite(p, static_cast<uint32_t>(64));
TRI_Free(TRI_UNKNOWN_MEM_ZONE, p); TRI_Free(TRI_UNKNOWN_MEM_ZONE, p);
} }

View File

@ -37,10 +37,12 @@ using namespace triagens::wal;
/// @brief create the logfile /// @brief create the logfile
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Logfile::Logfile (TRI_datafile_t* df) Logfile::Logfile (TRI_datafile_t* df,
SealStatusType sealStatus,
CollectionStatusType collectionStatus)
: _df(df), : _df(df),
_sealRequested(false), _sealStatus(sealStatus),
_collectionStatus(CollectionStatusType::UNCOLLECTED) { _collectionStatus(collectionStatus) {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -48,22 +50,79 @@ Logfile::Logfile (TRI_datafile_t* df)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Logfile::~Logfile () { Logfile::~Logfile () {
if (_df != nullptr) { this->close();
TRI_CloseDatafile(_df);
}
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- public methods // --SECTION-- public methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief create a new logfile
////////////////////////////////////////////////////////////////////////////////
Logfile* Logfile::create (std::string const& filename,
Logfile::IdType id,
uint32_t size) {
TRI_datafile_t* df = TRI_CreateDatafile(filename.c_str(), id, static_cast<TRI_voc_size_t>(size));
if (df == nullptr) {
int res = TRI_errno();
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("unable to create logfile '%s': %s",
filename.c_str(),
TRI_errno_string(res));
return nullptr;
}
}
Logfile* logfile = new Logfile(df, SealStatusType::UNKNOWN, CollectionStatusType::UNCOLLECTED);
return logfile;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief open an existing logfile
////////////////////////////////////////////////////////////////////////////////
Logfile* Logfile::open (std::string const& filename) {
TRI_datafile_t* df = TRI_OpenDatafile(filename.c_str());
if (df == nullptr) {
int res = TRI_errno();
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("unable to open logfile '%s': %s",
filename.c_str(),
TRI_errno_string(res));
return nullptr;
}
}
Logfile* logfile = new Logfile(df, SealStatusType::UNKNOWN, CollectionStatusType::UNCOLLECTED);
return logfile;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief close a logfile
////////////////////////////////////////////////////////////////////////////////
void Logfile::close () {
if (_df != nullptr) {
TRI_CloseDatafile(_df);
_df = nullptr;
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief seal a logfile /// @brief seal a logfile
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Logfile::seal () { void Logfile::seal () {
LOG_INFO("sealing logfile %llu", (unsigned long long) id()); LOG_INFO("sealing logfile %llu",
_sealRequested = true; (unsigned long long) id());
assert(_sealStatus == SealStatusType::UNSEALED);
_sealStatus = SealStatusType::REQUESTED;
} }
// Local Variables: // Local Variables:

View File

@ -53,11 +53,22 @@ namespace triagens {
typedef TRI_voc_fid_t IdType; typedef TRI_voc_fid_t IdType;
////////////////////////////////////////////////////////////////////////////////
/// @brief logfile seal status
////////////////////////////////////////////////////////////////////////////////
enum class SealStatusType : uint32_t {
UNKNOWN,
UNSEALED,
REQUESTED,
SEALED
};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief logfile collection status /// @brief logfile collection status
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
enum class CollectionStatusType { enum class CollectionStatusType : uint32_t {
UNCOLLECTED, UNCOLLECTED,
REQUESTED, REQUESTED,
DONE DONE
@ -82,7 +93,9 @@ namespace triagens {
/// @brief create a logfile /// @brief create a logfile
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Logfile (TRI_datafile_t*); Logfile (TRI_datafile_t*,
SealStatusType,
CollectionStatusType);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief destroy a logfile /// @brief destroy a logfile
@ -94,11 +107,31 @@ namespace triagens {
// --SECTION-- public methods // --SECTION-- public methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief create a new logfile
////////////////////////////////////////////////////////////////////////////////
static Logfile* create (std::string const&,
Logfile::IdType,
uint32_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief open an existing logfile
////////////////////////////////////////////////////////////////////////////////
static Logfile* open (std::string const&);
////////////////////////////////////////////////////////////////////////////////
/// @brief close a logfile
////////////////////////////////////////////////////////////////////////////////
void close ();
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief return the datafile pointer /// @brief return the datafile pointer
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
TRI_datafile_t* df () { inline TRI_datafile_t* df () const {
return _df; return _df;
} }
@ -106,7 +139,7 @@ namespace triagens {
/// @brief return the logfile id /// @brief return the logfile id
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Logfile::IdType id () const { inline Logfile::IdType id () const {
return _df->_fid; return _df->_fid;
} }
@ -114,7 +147,7 @@ namespace triagens {
/// @brief return the allocated size of the logfile /// @brief return the allocated size of the logfile
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
uint64_t allocatedSize () const { inline uint64_t allocatedSize () const {
return static_cast<uint64_t>(_df->_maximalSize); return static_cast<uint64_t>(_df->_maximalSize);
} }
@ -123,7 +156,7 @@ namespace triagens {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
uint64_t freeSize () const { uint64_t freeSize () const {
if (_df->_isSealed) { if (isSealed()) {
return 0; return 0;
} }
@ -150,17 +183,16 @@ namespace triagens {
/// @brief whether or not the logfile is sealed /// @brief whether or not the logfile is sealed
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool isSealed () const { inline bool isSealed () const {
// TODO: introduce a logfile status instead of this boolean return (_sealStatus == SealStatusType::SEALED);
return _sealRequested;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the logfile can be collected /// @brief whether or not the logfile can be collected
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool canCollect () const { inline bool canCollect () const {
return isSealed() && (_collectionStatus == CollectionStatusType::UNCOLLECTED); return (isSealed() && (_collectionStatus == CollectionStatusType::UNCOLLECTED));
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -198,10 +230,10 @@ namespace triagens {
TRI_datafile_t* _df; TRI_datafile_t* _df;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a seal was requested /// @brief logfile seal status
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool _sealRequested; SealStatusType _sealStatus;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief logfile collection status /// @brief logfile collection status

View File

@ -65,7 +65,7 @@ LogfileManager::LogfileManager (Configuration* configuration)
_maxEntrySize(configuration->maxEntrySize()), _maxEntrySize(configuration->maxEntrySize()),
_directory(configuration->directory()), _directory(configuration->directory()),
_regex(), _regex(),
_shutdown(false) { _shutdown(0) {
LOG_INFO("creating wal logfile manager"); LOG_INFO("creating wal logfile manager");
@ -142,15 +142,22 @@ int LogfileManager::startup () {
res = readShutdownInfo(); res = readShutdownInfo();
if (res != TRI_ERROR_NO_ERROR) { if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("could not open shutdown file '%s': %s", shutdownFile.c_str(), TRI_errno_string(res)); LOG_ERROR("could not open shutdown file '%s': %s",
shutdownFile.c_str(),
TRI_errno_string(res));
return res; return res;
} }
LOG_INFO("last tick: %llu, last collected: %llu",
(unsigned long long) _slots->lastTick(),
(unsigned long long) _lastCollectedId);
} }
res = openLogfiles(); res = openLogfiles();
if (res != TRI_ERROR_NO_ERROR) { if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("could not open wal logfiles: %s", TRI_errno_string(res)); LOG_ERROR("could not open wal logfiles: %s",
TRI_errno_string(res));
return res; return res;
} }
@ -193,11 +200,11 @@ int LogfileManager::startup () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void LogfileManager::shutdown () { void LogfileManager::shutdown () {
if (_shutdown) { if (_shutdown > 0) {
return; return;
} }
_shutdown = true; _shutdown = 1;
LOG_INFO("stopping collector thread"); LOG_INFO("stopping collector thread");
// stop threads // stop threads
@ -234,25 +241,21 @@ void LogfileManager::signalSync () {
/// @brief allocate space in a logfile for later writing /// @brief allocate space in a logfile for later writing
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Slot* LogfileManager::allocate (uint32_t size, int ctx) { SlotInfo LogfileManager::allocate (uint32_t size) {
/*
if (size > _maxEntrySize) { if (size > _maxEntrySize) {
// entry is too big // entry is too big
return LogEntry(TRI_ERROR_ARANGO_DOCUMENT_TOO_LARGE); return SlotInfo(TRI_ERROR_ARANGO_DOCUMENT_TOO_LARGE);
} }
*/
return _slots->nextUnused(size, ctx); return _slots->nextUnused(size);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief finalise a log entry /// @brief finalise a log entry
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int LogfileManager::finalise (Slot* slot) { void LogfileManager::finalise (SlotInfo& slotInfo) {
_slots->returnUsed(slot); _slots->returnUsed(slotInfo);
return TRI_ERROR_NO_ERROR;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -261,22 +264,20 @@ int LogfileManager::finalise (Slot* slot) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int LogfileManager::allocateAndWrite (void* mem, int LogfileManager::allocateAndWrite (void* mem,
uint32_t size, uint32_t size) {
int ctx) {
Slot* slot = allocate(size, ctx); SlotInfo slotInfo = allocate(size);
if (slot == nullptr) { if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
// TODO: return "real" error code return slotInfo.errorCode;
LOG_ERROR("no free slot!");
assert(false);
return TRI_ERROR_OUT_OF_MEMORY;
} }
TRI_df_marker_t* marker = static_cast<TRI_df_marker_t*>(slot->mem()); assert(slotInfo.slot != nullptr);
TRI_df_marker_t* marker = static_cast<TRI_df_marker_t*>(slotInfo.slot->mem());
// write tick into marker // write tick into marker
marker->_tick = slot->tick(); marker->_tick = slotInfo.slot->tick();
// set initial crc to 0 // set initial crc to 0
marker->_crc = 0; marker->_crc = 0;
@ -286,9 +287,10 @@ int LogfileManager::allocateAndWrite (void* mem,
crc = TRI_BlockCrc32(crc, static_cast<char const*>(mem), static_cast<TRI_voc_size_t>(size)); crc = TRI_BlockCrc32(crc, static_cast<char const*>(mem), static_cast<TRI_voc_size_t>(size));
marker->_crc = TRI_FinalCrc32(crc); marker->_crc = TRI_FinalCrc32(crc);
memcpy(slot->mem(), mem, static_cast<TRI_voc_size_t>(size)); memcpy(slotInfo.slot->mem(), mem, static_cast<TRI_voc_size_t>(size));
return finalise(slot); finalise(slotInfo);
return slotInfo.errorCode;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -298,10 +300,10 @@ int LogfileManager::allocateAndWrite (void* mem,
int LogfileManager::sealLogfile (Logfile* logfile) { int LogfileManager::sealLogfile (Logfile* logfile) {
assert(logfile != nullptr); assert(logfile != nullptr);
LOG_INFO("sealing logfile"); {
WRITE_LOCKER(_logfilesLock);
WRITE_LOCKER(_logfilesLock); logfile->seal();
logfile->seal(); }
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
@ -616,25 +618,21 @@ int LogfileManager::inventory () {
int LogfileManager::openLogfiles () { int LogfileManager::openLogfiles () {
WRITE_LOCKER(_logfilesLock); WRITE_LOCKER(_logfilesLock);
for (auto it = _logfiles.begin(); it != _logfiles.end(); ++it) { for (auto it = _logfiles.begin(); it != _logfiles.end(); ) {
Logfile::IdType const id = (*it).first; Logfile::IdType const id = (*it).first;
std::string const filename = logfileName(id); std::string const filename = logfileName(id);
assert((*it).second == nullptr); assert((*it).second == nullptr);
TRI_datafile_t* df = TRI_OpenDatafile(filename.c_str()); Logfile* logfile = Logfile::open(filename);
if (df == nullptr) { if (logfile == nullptr) {
int res = TRI_errno(); _logfiles.erase(it++);
}
if (res != TRI_ERROR_NO_ERROR) { else {
LOG_ERROR("unable to open logfile '%s': %s", filename.c_str(), TRI_errno_string(res)); (*it).second = Logfile::open(filename);
return res; ++it;
}
} }
// TODO: the last logfile is probably still a journal. must fix the "false" value
(*it).second = new Logfile(df);
} }
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
@ -648,9 +646,9 @@ int LogfileManager::allocateDatafile () {
Logfile::IdType const id = nextId(); Logfile::IdType const id = nextId();
std::string const filename = logfileName(id); std::string const filename = logfileName(id);
TRI_datafile_t* df = TRI_CreateDatafile(filename.c_str(), id, static_cast<TRI_voc_size_t>(_configuration->filesize())); Logfile* logfile = Logfile::create(filename.c_str(), id, _configuration->filesize());
if (df == nullptr) { if (logfile == nullptr) {
int res = TRI_errno(); int res = TRI_errno();
LOG_ERROR("unable to create datafile: %s", TRI_errno_string(res)); LOG_ERROR("unable to create datafile: %s", TRI_errno_string(res));
@ -658,7 +656,7 @@ int LogfileManager::allocateDatafile () {
} }
WRITE_LOCKER(_logfilesLock); WRITE_LOCKER(_logfilesLock);
_logfiles.insert(make_pair(id, new Logfile(df))); _logfiles.insert(make_pair(id, logfile));
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }

View File

@ -32,6 +32,7 @@
#include "Basics/Mutex.h" #include "Basics/Mutex.h"
#include "Basics/ReadWriteLock.h" #include "Basics/ReadWriteLock.h"
#include "Wal/Logfile.h" #include "Wal/Logfile.h"
#include "Wal/Slots.h"
#include <regex.h> #include <regex.h>
@ -42,7 +43,6 @@ namespace triagens {
class CollectorThread; class CollectorThread;
class Configuration; class Configuration;
class Slot; class Slot;
class Slots;
class SynchroniserThread; class SynchroniserThread;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -122,13 +122,13 @@ namespace triagens {
/// @brief reserve space in a logfile /// @brief reserve space in a logfile
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Slot* allocate (uint32_t, int); SlotInfo allocate (uint32_t);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief finalise a log entry /// @brief finalise a log entry
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int finalise (Slot*); void finalise (SlotInfo&);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief write data into the logfile /// @brief write data into the logfile
@ -136,8 +136,7 @@ namespace triagens {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int allocateAndWrite (void*, int allocateAndWrite (void*,
uint32_t, uint32_t);
int);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief seal a logfile /// @brief seal a logfile
@ -361,7 +360,7 @@ namespace triagens {
/// @brief whether or not we have been shutdown already /// @brief whether or not we have been shutdown already
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool _shutdown; volatile sig_atomic_t _shutdown;
}; };

120
arangod/Wal/Slot.cpp Normal file
View File

@ -0,0 +1,120 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief Write-ahead log slot
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2013 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 Jan Steemann
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "Wal/Slot.h"
using namespace triagens::wal;
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief create a slot
////////////////////////////////////////////////////////////////////////////////
Slot::Slot ()
: _tick(0),
_logfileId(0),
_mem(nullptr),
_size(0),
_status(StatusType::UNUSED) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destroy a slot
////////////////////////////////////////////////////////////////////////////////
Slot::~Slot () {
}
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief return the slot status as a string
////////////////////////////////////////////////////////////////////////////////
std::string Slot::statusText () const {
switch (_status) {
case StatusType::UNUSED:
return "unused";
case StatusType::USED:
return "used";
case StatusType::RETURNED:
return "returned";
}
}
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief mark as slot as used
////////////////////////////////////////////////////////////////////////////////
void Slot::setUnused () {
assert(isReturned());
_tick = 0;
_logfileId = 0;
_mem = nullptr;
_size = 0;
_status = StatusType::UNUSED;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief mark as slot as used
////////////////////////////////////////////////////////////////////////////////
void Slot::setUsed (void* mem,
uint32_t size,
Logfile::IdType logfileId,
Slot::TickType tick) {
assert(isUnused());
_tick = tick;
_logfileId = logfileId;
_mem = mem;
_size = size;
_status = StatusType::USED;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief mark as slot as returned
////////////////////////////////////////////////////////////////////////////////
void Slot::setReturned () {
assert(isUsed());
_status = StatusType::RETURNED;
}
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -33,114 +33,187 @@
namespace triagens { namespace triagens {
namespace wal { namespace wal {
class Slots; class Slots;
// -----------------------------------------------------------------------------
// --SECTION-- class Slot
// -----------------------------------------------------------------------------
class Slot { class Slot {
friend class Slots; friend class Slots;
// -----------------------------------------------------------------------------
// --SECTION-- typedefs
// -----------------------------------------------------------------------------
public: public:
////////////////////////////////////////////////////////////////////////////////
/// @brief tick typedef
////////////////////////////////////////////////////////////////////////////////
typedef TRI_voc_tick_t TickType; typedef TRI_voc_tick_t TickType;
public: ////////////////////////////////////////////////////////////////////////////////
/// @brief slot status typedef
////////////////////////////////////////////////////////////////////////////////
enum class StatusType { enum class StatusType : uint32_t {
UNUSED = 0, UNUSED = 0,
USED = 1, USED = 1,
RETURNED = 2 RETURNED = 2
}; };
private: // -----------------------------------------------------------------------------
Slot (size_t slotIndex) // --SECTION-- constructors and destructors
: _status(StatusType::UNUSED), // -----------------------------------------------------------------------------
_tick(0),
_logfileId(0),
_mem(nullptr),
_size(0) {
}
~Slot () { ////////////////////////////////////////////////////////////////////////////////
} /// @brief create a slot
////////////////////////////////////////////////////////////////////////////////
private:
Slot ();
////////////////////////////////////////////////////////////////////////////////
/// @brief destroy a slot
////////////////////////////////////////////////////////////////////////////////
~Slot ();
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
public: public:
std::string statusText () const { ////////////////////////////////////////////////////////////////////////////////
switch (_status) { /// @brief return the tick assigned to the slot
case StatusType::UNUSED: ////////////////////////////////////////////////////////////////////////////////
return "unused";
case StatusType::USED:
return "used";
case StatusType::RETURNED:
return "returned";
}
}
Slot::TickType tick () const { inline Slot::TickType tick () const {
return _tick; return _tick;
} }
Logfile::IdType logfileId () const { ////////////////////////////////////////////////////////////////////////////////
/// @brief return the logfile id assigned to the slot
////////////////////////////////////////////////////////////////////////////////
inline Logfile::IdType logfileId () const {
return _logfileId; return _logfileId;
} }
void* mem () const { ////////////////////////////////////////////////////////////////////////////////
/// @brief return the raw memory pointer assigned to the slot
////////////////////////////////////////////////////////////////////////////////
inline void* mem () const {
return _mem; return _mem;
} }
uint32_t size () const { ////////////////////////////////////////////////////////////////////////////////
/// @brief return the memory size assigned to the slot
////////////////////////////////////////////////////////////////////////////////
inline uint32_t size () const {
return _size; return _size;
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief return the slot status as a string
////////////////////////////////////////////////////////////////////////////////
std::string statusText () const;
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
private: private:
bool isUnused () const {
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the slot is unused
////////////////////////////////////////////////////////////////////////////////
inline bool isUnused () const {
return _status == StatusType::UNUSED; return _status == StatusType::UNUSED;
} }
bool isUsed () const { ////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the slot is used
////////////////////////////////////////////////////////////////////////////////
inline bool isUsed () const {
return _status == StatusType::USED; return _status == StatusType::USED;
} }
bool isReturned () const { ////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the slot is returned
////////////////////////////////////////////////////////////////////////////////
inline bool isReturned () const {
return _status == StatusType::RETURNED; return _status == StatusType::RETURNED;
} }
void setUnused () { ////////////////////////////////////////////////////////////////////////////////
assert(isReturned()); /// @brief mark as slot as unused
_status = StatusType::UNUSED; ////////////////////////////////////////////////////////////////////////////////
_tick = 0;
_logfileId = 0;
_mem = nullptr;
_size = 0;
}
void setUsed (void* mem, void setUnused ();
uint32_t size,
Logfile::IdType logfileId,
Slot::TickType tick) {
assert(isUnused());
_status = StatusType::USED;
_tick = tick;
_logfileId = logfileId;
_mem = mem;
_size = size;
}
void setReturned () { ////////////////////////////////////////////////////////////////////////////////
assert(isUsed()); /// @brief mark as slot as used
_status = StatusType::RETURNED; ////////////////////////////////////////////////////////////////////////////////
}
void setUsed (void*,
uint32_t,
Logfile::IdType,
Slot::TickType);
////////////////////////////////////////////////////////////////////////////////
/// @brief mark as slot as returned
////////////////////////////////////////////////////////////////////////////////
void setReturned ();
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
private: private:
StatusType _status; ////////////////////////////////////////////////////////////////////////////////
/// @brief slot tick
////////////////////////////////////////////////////////////////////////////////
Slot::TickType _tick; Slot::TickType _tick;
////////////////////////////////////////////////////////////////////////////////
/// @brief slot logfile id
////////////////////////////////////////////////////////////////////////////////
Logfile::IdType _logfileId; Logfile::IdType _logfileId;
////////////////////////////////////////////////////////////////////////////////
/// @brief slot raw memory pointer
////////////////////////////////////////////////////////////////////////////////
void* _mem; void* _mem;
////////////////////////////////////////////////////////////////////////////////
/// @brief slot raw memory size
////////////////////////////////////////////////////////////////////////////////
uint32_t _size; uint32_t _size;
////////////////////////////////////////////////////////////////////////////////
/// @brief slot status
////////////////////////////////////////////////////////////////////////////////
StatusType _status;
}; };
} }

View File

@ -58,7 +58,7 @@ Slots::Slots (LogfileManager* logfileManager,
_readOnly(false) { _readOnly(false) {
for (size_t i = 0; i < _numberOfSlots; ++i) { for (size_t i = 0; i < _numberOfSlots; ++i) {
_slots[i] = new Slot(i); _slots[i] = new Slot();
} }
} }
@ -106,7 +106,7 @@ Slot::TickType Slots::lastTick () {
/// @brief return the next unused slot /// @brief return the next unused slot
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Slot* Slots::nextUnused (uint32_t size, int ctx) { SlotInfo Slots::nextUnused (uint32_t size) {
// we need to use the aligned size for writing // we need to use the aligned size for writing
size = TRI_DF_ALIGN_BLOCK(size); size = TRI_DF_ALIGN_BLOCK(size);
@ -117,7 +117,7 @@ Slot* Slots::nextUnused (uint32_t size, int ctx) {
MUTEX_LOCKER(_lock); MUTEX_LOCKER(_lock);
if (_readOnly) { if (_readOnly) {
return nullptr; return SlotInfo(TRI_ERROR_ARANGO_READ_ONLY);
} }
Slot* slot = _slots[_handoutIndex]; Slot* slot = _slots[_handoutIndex];
@ -155,12 +155,15 @@ Slot* Slots::nextUnused (uint32_t size, int ctx) {
TRI_df_marker_t* mem; TRI_df_marker_t* mem;
int res = TRI_ReserveElementDatafile(_logfile->df(), static_cast<TRI_voc_size_t>(size), &mem, 32 * 1024 * 1024); int res = TRI_ReserveElementDatafile(_logfile->df(), static_cast<TRI_voc_size_t>(size), &mem, 32 * 1024 * 1024);
if (res != TRI_ERROR_NO_ERROR || mem == nullptr) { if (res != TRI_ERROR_NO_ERROR) {
return nullptr; return SlotInfo(res);
} }
assert(mem != nullptr);
assert(_freeSlots > 0); assert(_freeSlots > 0);
_freeSlots--; _freeSlots--;
slot->setUsed(static_cast<void*>(mem), size, _logfile->id(), ++_lastTick); slot->setUsed(static_cast<void*>(mem), size, _logfile->id(), ++_lastTick);
if (++_handoutIndex ==_numberOfSlots) { if (++_handoutIndex ==_numberOfSlots) {
@ -168,7 +171,7 @@ Slot* Slots::nextUnused (uint32_t size, int ctx) {
_handoutIndex = 0; _handoutIndex = 0;
} }
return slot; return SlotInfo(slot);
} }
} }
@ -195,12 +198,12 @@ Slot* Slots::nextUnused (uint32_t size, int ctx) {
/// @brief return a used slot, allowing its synchronisation /// @brief return a used slot, allowing its synchronisation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Slots::returnUsed (Slot* slot) { void Slots::returnUsed (SlotInfo& slotInfo) {
assert(slot != nullptr); assert(slotInfo.slot != nullptr);
{ {
MUTEX_LOCKER(_lock); MUTEX_LOCKER(_lock);
slot->setReturned(); slotInfo.slot->setReturned();
} }
_logfileManager->signalSync(); _logfileManager->signalSync();

View File

@ -40,6 +40,29 @@ namespace triagens {
class LogfileManager; class LogfileManager;
// -----------------------------------------------------------------------------
// --SECTION-- struct SlotInfo
// -----------------------------------------------------------------------------
struct SlotInfo {
explicit SlotInfo (int errorCode)
: slot(nullptr),
errorCode(errorCode) {
}
explicit SlotInfo (Slot* slot)
: slot(slot),
errorCode(TRI_ERROR_NO_ERROR) {
}
SlotInfo ()
: SlotInfo(TRI_ERROR_NO_ERROR) {
}
Slot* slot;
int errorCode;
};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- class Slots // --SECTION-- class Slots
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -96,13 +119,13 @@ namespace triagens {
/// @brief return the next unused slot /// @brief return the next unused slot
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Slot* nextUnused (uint32_t, int); SlotInfo nextUnused (uint32_t);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief return a used slot, allowing its synchronisation /// @brief return a used slot, allowing its synchronisation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void returnUsed (Slot*); void returnUsed (SlotInfo&);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief get the next synchronisable region /// @brief get the next synchronisable region

View File

@ -1,59 +0,0 @@
/*
#documentsTable thead {
border: 0 !important;
}
*/
#tableDiv table.dataTable td {
padding:12px 18px !important;
}
table.dataTable thead th {
border-bottom:none;
cursor: default !important;
}
table.arangoDataTable.dataTable td {
padding:10px 18px;
}
.arangoDataTable thead {
font-weight: 400 !important;
background-color: #FFFFFF !important;
text-align: left;
}
.arangoDataTable {
width: 100% !important;
position: relative;
table-layout:fixed !important;
border-spacing:0 0px;
}
.arangoDataTable.dataTable thead tr {
border-bottom: 1px solid #C2C2C2;
}
table.arangoDataTable tr {
cursor: pointer;
}
table.arangoDataTable.noPointer tr {
cursor: default;
}
.arangoDataTable .key {
margin-top: 4px;
}
/* Odd / Even coloring */
.api-container ul#resources > li.resource:nth-child(even),
table.arangoDataTable tr.even {
background-color: #FFFFFF;
}
.api-container ul#resources > li.resource:nth-child(odd),
table.arangoDataTable tr.odd {
background-color: #F1F0EE;
}

View File

@ -1,9 +1,62 @@
table.dataTable thead th { .arangoDataTable {
font-weight: 400 !important; border-spacing: 0 0;
padding: 10px 14px; position: relative;
table-layout: fixed !important;
width: 100% !important;
thead {
background-color: #fff !important;
font-weight: 400 !important;
text-align: left;
th {
border-bottom: 0;
cursor: default !important;
font-weight: 400 !important;
padding: 10px 14px !important;
}
tr {
border-bottom: 1px solid #c2c2c2;
}
}
tr {
cursor: pointer;
}
td {
padding: 10px 18px !important;
}
.key {
margin-top: 4px;
}
.dataTable {
.noPointer tr {
cursor: default;
}
}
}
// Odd / Even coloring
.api-container #resources > li.resource:nth-child(even),
table.arangoDataTable tr.even {
background-color: #fff;
}
.api-container #resources > li.resource:nth-child(odd),
table.arangoDataTable tr.odd {
background-color: #f1f0ee;
} }
// TODO Hard cleanup // TODO Hard cleanup
#tableDiv table.dataTable td {
padding: 12px 18px !important;
}
#documentsTableID_length, #documentsTableID_length,
#documentsTableID_filter { #documentsTableID_filter {
display: none; display: none;
@ -47,7 +100,7 @@ table.dataTable thead th {
} }
.prettify { .prettify {
border: 0 !important; border: none !important;
font-size: 1em !important; font-size: 1em !important;
margin: 0 !important; margin: 0 !important;
padding: 0 !important; padding: 0 !important;

View File

@ -3486,138 +3486,41 @@ input.gv-radio-button {
margin-top: 3px; margin-top: 3px;
width: auto; } width: auto; }
.collectionTh { .arangoDataTable {
font-family: 'Open Sans', sans-serif !important; border-spacing: 0 0;
font-size: 14px;
font-weight: 400 !important;
text-align: left;
width: 20% !important; }
.collectionTh input,
.collectionTh select,
.collectionTh textarea {
margin-top: 10px; }
.collectionInfoTh {
min-width: 60px;
text-align: left;
width: 320px; }
.addCollection table tr {
border-bottom: 0 !important;
height: 53px; }
.addCollection .icon_arangodb_info {
margin-left: 20px !important;
position: relative; position: relative;
top: 2px !important; } table-layout: fixed !important;
.addCollection .accordion { width: 100% !important; }
margin-top: 10px; } .arangoDataTable thead {
.addCollection .collectionThSec { background-color: #fff !important;
width: 320px !important; } font-weight: 400 !important;
.addCollection .collectionTh { text-align: left; }
width: 96px; } .arangoDataTable thead th {
.addCollection .modalInput { border-bottom: 0;
width: 320px; } cursor: default !important;
.addCollection .modalSelect { font-weight: 400 !important;
width: 334px; } padding: 10px 14px !important; }
.addCollection .accordion-toggle { .arangoDataTable thead tr {
width: 457px !important; } border-bottom: 1px solid #c2c2c2; }
.arangoDataTable tr {
cursor: pointer; }
.arangoDataTable td {
padding: 10px 18px !important; }
.arangoDataTable .key {
margin-top: 4px; }
.arangoDataTable .dataTable .noPointer tr {
cursor: default; }
.change-collection .tab-content { .api-container #resources > li.resource:nth-child(even),
min-height: 230px; } table.arangoDataTable tr.even {
.change-collection input { background-color: #fff; }
width: 384px !important; }
.change-collection select {
width: 398px !important; }
.show-collection .tab-content { .api-container #resources > li.resource:nth-child(odd),
min-height: 200px; } table.arangoDataTable tr.odd {
background-color: #f1f0ee; }
.collectionInfoTh { #tableDiv table.dataTable td {
width: 320px; } padding: 12px 18px !important; }
.collectionInfoTh2 {
font-family: 'Open Sans', sans-serif !important;
font-weight: 400 !important;
text-align: left;
width: 150px; }
.collection-info-figures table {
float: left;
margin-left: 0;
margin-right: 0;
margin-top: 0;
min-width: 200px;
padding: 3px;
text-align: left; }
.figures1,
.figures2 {
margin-bottom: 20px;
width: 255px; }
.figures2 {
margin-left: 20px !important; }
.figures3 {
margin-bottom: 0;
width: 100%; }
.figuresHeader {
border-bottom: 1px solid #c2c2c2; }
.figuresHeader th {
font-family: 'Open Sans', sans-serif !important;
font-weight: 400 !important; }
#collectionIndexTable {
margin-left: 0;
width: 100%; }
#infoTab,
#collectionTab {
border-bottom: 0;
margin-bottom: 1px;
padding-bottom: 0;
padding-right: 10px; }
#infoTab li,
#collectionTab li {
float: right; }
#infoTab a,
#collectionTab a {
background-color: #f1f0ee;
border-bottom: 1px solid #888888;
border-radius: 0 !important;
color: black;
font-size: 13px !important;
height: 21px;
margin-bottom: -1px;
margin-right: 4px;
padding: 4px !important; }
#infoTab .active > a,
#collectionTab .active > a {
background-color: white;
border-color: #888888 #888888 transparent !important; }
#tab-content-collection-info #info,
#tab-content-collection-info .collection-info-figures,
#tab-content-collection-info #index {
border-top: 1px solid #888888 !important;
margin-left: 0 !important;
padding-top: 10px; }
#confirmCreateEdge {
margin-left: 20px; }
.collection-info-figures .icon_arangodb_info {
position: relative !important;
right: -4px !important; }
table.dataTable thead th {
font-weight: 400 !important;
padding: 10px 14px; }
#documentsTableID_length, #documentsTableID_length,
#documentsTableID_filter { #documentsTableID_filter {
@ -3655,7 +3558,7 @@ table.dataTable thead th {
padding-left: 10px; } padding-left: 10px; }
.prettify { .prettify {
border: 0 !important; border: none !important;
font-size: 1em !important; font-size: 1em !important;
margin: 0 !important; margin: 0 !important;
padding: 0 !important; } padding: 0 !important; }

View File

@ -54,7 +54,7 @@
// General Dialogs // General Dialogs
@import 'dialogs'; @import 'dialogs';
// Collections // Collections
@import 'collection'; //@import 'collection';
// Data Tables, TODO: might all be superflous // Data Tables, TODO: might all be superflous