1
0
Fork 0
arangodb/arangod/StorageEngine/MMFilesCompactorThread.h

145 lines
5.2 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 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 ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGOD_STORAGE_ENGINE_MM_FILES_COMPACTOR_THREAD_H
#define ARANGOD_STORAGE_ENGINE_MM_FILES_COMPACTOR_THREAD_H 1
#include "Basics/Common.h"
#include "Basics/ConditionVariable.h"
#include "Basics/Thread.h"
#include "VocBase/voc-types.h"
struct TRI_datafile_t;
struct TRI_df_marker_t;
struct TRI_vocbase_t;
namespace arangodb {
struct CompactionContext;
class LogicalCollection;
class Transaction;
class MMFilesCompactorThread final : public Thread {
private:
/// @brief compaction instruction for a single datafile
struct compaction_info_t {
TRI_datafile_t* _datafile;
bool _keepDeletions;
};
/// @brief auxiliary struct used when initializing compaction
struct CompactionInitialContext {
arangodb::Transaction* _trx;
LogicalCollection* _collection;
int64_t _targetSize;
TRI_voc_fid_t _fid;
bool _keepDeletions;
bool _failed;
CompactionInitialContext(arangodb::Transaction* trx, LogicalCollection* collection)
: _trx(trx), _collection(collection), _targetSize(0), _fid(0), _keepDeletions(false), _failed(false) {}
};
public:
explicit MMFilesCompactorThread(TRI_vocbase_t* vocbase);
~MMFilesCompactorThread();
void signal();
/// @brief callback to drop a datafile
static void DropDatafileCallback(TRI_datafile_t* datafile, LogicalCollection* collection);
/// @brief callback to rename a datafile
static void RenameDatafileCallback(TRI_datafile_t* datafile, TRI_datafile_t* compactor, LogicalCollection* collection);
protected:
void run() override;
private:
/// @brief calculate the target size for the compactor to be created
CompactionInitialContext getCompactionContext(
arangodb::Transaction* trx, LogicalCollection* collection,
std::vector<compaction_info_t> const& toCompact);
/// @brief compact the specified datafiles
void compactDatafiles(LogicalCollection* collection, std::vector<compaction_info_t> const&);
/// @brief checks all datafiles of a collection
bool compactCollection(LogicalCollection* collection, bool& wasBlocked);
int removeCompactor(LogicalCollection* collection, TRI_datafile_t* datafile);
/// @brief remove an empty datafile
int removeDatafile(LogicalCollection* collection, TRI_datafile_t* datafile);
/// @brief determine the number of documents in the collection
uint64_t getNumberOfDocuments(LogicalCollection* collection);
/// @brief write a copy of the marker into the datafile
int copyMarker(TRI_datafile_t* compactor, TRI_df_marker_t const* marker,
TRI_df_marker_t** result);
/// @brief wait time between compaction runs when idle
static constexpr unsigned compactionSleepTime() { return 1000 * 1000; }
/// @brief compaction interval in seconds
static constexpr double compactionCollectionInterval() { return 10.0; }
/// @brief maximum number of files to compact and concat
static constexpr unsigned maxFiles() { return 3; }
/// @brief maximum multiple of journal filesize of a compacted file
/// a value of 3 means that the maximum filesize of the compacted file is
/// 3 x (collection->journalSize)
static constexpr unsigned maxSizeFactor() { return 3; }
static constexpr unsigned smallDatafileSize() { return 128 * 1024; }
/// @brief maximum filesize of resulting compacted file
static constexpr uint64_t maxResultFilesize() { return 128 * 1024 * 1024; }
/// @brief minimum number of deletion marker in file from which on we will
/// compact it if nothing else qualifies file for compaction
static constexpr int64_t deadNumberThreshold() { return 16384; }
/// @brief minimum size of dead data (in bytes) in a datafile that will make
/// the datafile eligible for compaction at all.
/// Any datafile with less dead data than the threshold will not become a
/// candidate for compaction.
static constexpr int64_t deadSizeThreshold() { return 128 * 1024; }
/// @brief percentage of dead documents in a datafile that will trigger the
/// compaction
/// for example, if the collection contains 800 bytes of alive and 400 bytes of
/// dead documents, the share of the dead documents is 400 / (400 + 800) = 33 %.
/// if this value if higher than the threshold, the datafile will be compacted
static constexpr double deadShare() { return 0.1; }
private:
TRI_vocbase_t* _vocbase;
arangodb::basics::ConditionVariable _condition;
};
}
#endif