0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
CommitLog.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; version 3 of the
9  * License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
26 
27 #include <Common/Compat.h>
28 
29 #include "CommitLog.h"
30 
35 
36 #include <AsyncComm/Protocol.h>
37 
38 #include <Common/Checksum.h>
39 #include <Common/Config.h>
40 #include <Common/DynamicBuffer.h>
41 #include <Common/Error.h>
42 #include <Common/FileUtils.h>
43 #include <Common/Logger.h>
44 #include <Common/StringExt.h>
45 #include <Common/Time.h>
46 #include <Common/md5.h>
47 
48 #include <cassert>
49 #include <chrono>
50 
51 using namespace Hypertable;
52 using namespace std;
53 
54 const char CommitLog::MAGIC_DATA[10] =
55  { 'C','O','M','M','I','T','D','A','T','A' };
56 const char CommitLog::MAGIC_LINK[10] =
57  { 'C','O','M','M','I','T','L','I','N','K' };
58 
59 
60 CommitLog::CommitLog(FilesystemPtr &fs, const string &log_dir, bool is_meta)
61  : CommitLogBase(log_dir), m_fs(fs) {
62  initialize(log_dir, Config::properties, 0, is_meta);
63 }
64 
66  close();
67 }
68 
69 void
70 CommitLog::initialize(const string &log_dir, PropertiesPtr &props,
71  CommitLogBase *init_log, bool is_meta) {
72  string compressor;
73 
74  m_log_dir = log_dir;
76  m_needs_roll = false;
77  m_replication = -1;
78 
79  if (is_meta)
80  m_replication = props->get_i32("Hypertable.Metadata.Replication");
81  else
82  m_replication = props->get_i32("Hypertable.RangeServer.Data.DefaultReplication");
83 
84  SubProperties cfg(props, "Hypertable.CommitLog.");
85 
86  HT_TRY("getting commit log properites",
87  m_max_fragment_size = cfg.get_i64("RollLimit");
88  compressor = cfg.get_str("Compressor"));
89 
91 
92  boost::trim_right_if(m_log_dir, boost::is_any_of("/"));
93 
94  m_range_reference_required = props->get_bool("Hypertable.RangeServer.CommitLog.FragmentRemoval.RangeReferenceRequired");
95 
96  if (init_log) {
99  stitch_in(init_log);
100  for (const auto frag : m_fragment_queue) {
101  if (frag->num >= m_cur_fragment_num)
102  m_cur_fragment_num = frag->num + 1;
103  }
104  }
105  else { // chose one past the max one found in the directory
106  uint32_t num;
107  std::vector<Filesystem::Dirent> listing;
108  m_fs->readdir(m_log_dir, listing);
109  for (size_t i=0; i<listing.size(); i++) {
110  num = atoi(listing[i].name.c_str());
111  if (num >= m_cur_fragment_num)
112  m_cur_fragment_num = num + 1;
113  }
114  }
115 
117  HT_INFOF("Range reference for '%s' is required", m_log_dir.c_str());
118  else
119  HT_INFOF("Range reference for '%s' is NOT required", m_log_dir.c_str());
120 
122 
123  try {
124  m_fs->mkdirs(m_log_dir);
125  m_fd = m_fs->create(m_cur_fragment_fname, Filesystem::OPEN_FLAG_OVERWRITE,
126  -1, m_replication, -1);
129  }
130  catch (Hypertable::Exception &e) {
131  HT_ERRORF("Problem initializing commit log '%s' - %s (%s)",
132  m_log_dir.c_str(), e.what(), Error::get_text(e.code()));
133  m_fd = -1;
134  throw;
135  }
136 }
137 
138 
140  return get_ts64();
141 }
142 
144  lock_guard<mutex> lock(m_mutex);
145  int error {};
146 
147  try {
148  if (m_fd == -1)
149  return Error::CLOSED;
150  m_fs->flush(m_fd);
151  }
152  catch (Exception &e) {
153  HT_ERRORF("Problem flushing commit log: %s: %s",
154  m_cur_fragment_fname.c_str(), e.what());
155  error = e.code();
156  }
157 
158  return error;
159 }
160 
162  lock_guard<mutex> lock(m_mutex);
163  int error {};
164 
165  try {
166  if (m_fd == -1)
167  return Error::CLOSED;
168  m_fs->sync(m_fd);
169  }
170  catch (Exception &e) {
171  HT_ERRORF("Problem syncing commit log: %s: %s",
172  m_cur_fragment_fname.c_str(), e.what());
173  error = e.code();
174  }
175 
176  return error;
177 }
178 
179 
180 int
181 CommitLog::write(uint64_t cluster_id, DynamicBuffer &buffer, int64_t revision,
182  Filesystem::Flags flags) {
183  int error;
184  BlockHeaderCommitLog header(MAGIC_DATA, revision, cluster_id);
185 
186  if (m_needs_roll) {
187  lock_guard<mutex> lock(m_mutex);
188  if ((error = roll()) != Error::OK)
189  return error;
190  }
191 
195  if ((error = compress_and_write(buffer, &header, revision, flags)) != Error::OK)
196  return error;
197 
202  lock_guard<mutex> lock(m_mutex);
203  if ((error = roll()) != Error::OK)
204  return error;
205  }
206 
207  return Error::OK;
208 }
209 
210 
211 int CommitLog::link_log(uint64_t cluster_id, CommitLogBase *log_base) {
212  lock_guard<mutex> lock(m_mutex);
213  int error;
214  int64_t link_revision = log_base->get_latest_revision();
215  BlockHeaderCommitLog header(MAGIC_LINK, link_revision, cluster_id);
216 
217  DynamicBuffer input;
218  string &log_dir = log_base->get_log_dir();
219 
220  if (m_linked_log_hashes.count(md5_hash(log_dir.c_str())) > 0) {
221  HT_WARNF("Skipping log %s because it is already linked in", log_dir.c_str());
222  return Error::OK;
223  }
224 
225  if (m_needs_roll) {
226  if ((error = roll()) != Error::OK)
227  return error;
228  }
229 
230  HT_INFOF("clgc Linking log %s into fragment %d; link_rev=%lld latest_rev=%lld",
231  log_dir.c_str(), m_cur_fragment_num, (Lld)link_revision, (Lld)m_latest_revision);
232 
233  HT_ASSERT(link_revision > 0);
234 
235  if (link_revision > m_latest_revision)
236  m_latest_revision = link_revision;
237 
238  input.ensure(header.encoded_length());
239 
240  header.set_revision(link_revision);
242  header.set_data_length(log_dir.length() + 1);
243  header.set_data_zlength(log_dir.length() + 1);
244  header.set_data_checksum(fletcher32(log_dir.c_str(), log_dir.length()+1));
245 
246  header.encode(&input.ptr);
247  input.add(log_dir.c_str(), log_dir.length() + 1);
248 
249  try {
250  size_t amount = input.fill();
251  StaticBuffer send_buf(input);
252  CommitLogFileInfo *file_info = 0;
253 
254  if (m_fd == -1)
255  return Error::CLOSED;
256 
257  m_fs->append(m_fd, send_buf);
258  m_cur_fragment_length += amount;
259 
260  if ((error = roll(&file_info)) != Error::OK)
261  return error;
262 
263  file_info->verify();
264  file_info->purge_dirs.insert(log_dir);
265 
266  for (auto fi : log_base->fragment_queue()) {
267  if (fi->parent == 0) {
268  fi->parent = file_info;
269  file_info->references++;
270  }
271  m_fragment_queue.push_back(fi);
272  }
273  log_base->fragment_queue().clear();
274 
275  struct LtClfip swo;
276  sort(m_fragment_queue.begin(), m_fragment_queue.end(), swo);
277 
278  }
279  catch (Hypertable::Exception &e) {
280  HT_ERRORF("Problem linking external log into commit log - %s", e.what());
281  return e.code();
282  }
283 
284  m_linked_log_hashes.insert(md5_hash(log_dir.c_str()));
285 
286  return Error::OK;
287 }
288 
289 
291  lock_guard<mutex> lock(m_mutex);
292 
293  try {
294  if (m_fd >= 0) {
295  m_fs->close(m_fd);
296  m_fd = -1;
297  }
298  }
299  catch (Hypertable::Exception &e) {
300  HT_ERRORF("Problem closing commit log file '%s' - %s (%s)",
301  m_cur_fragment_fname.c_str(), e.what(),
302  Error::get_text(e.code()));
303  return e.code();
304  }
305 
306  return Error::OK;
307 }
308 
309 
310 int CommitLog::purge(int64_t revision, StringSet &remove_ok_logs,
311  StringSet &removed_logs, string *trace) {
312  lock_guard<mutex> lock(m_mutex);
313 
314  if (m_fd == -1)
315  return Error::CLOSED;
316 
317  if (trace) {
318  *trace += format("--- Reap set begin (%s) ---\n", m_log_dir.c_str());
319  for (const auto fi : m_reap_set)
320  *trace += fi->to_str(remove_ok_logs) + "\n";
321  *trace += format("--- Reap set end (%s) ---\n", m_log_dir.c_str());
322  }
323 
324  // Process "reap" set
325  std::set<CommitLogFileInfo *>::iterator rm_iter, iter = m_reap_set.begin();
326  while (iter != m_reap_set.end()) {
327  if ((*iter)->references == 0 &&
328  ((*iter)->remove_ok(remove_ok_logs) || !m_range_reference_required)) {
329  remove_file_info(*iter, removed_logs);
330  delete *iter;
331  rm_iter = iter++;
332  m_reap_set.erase(rm_iter);
333  }
334  else
335  ++iter;
336  }
337 
338  CommitLogFileInfo *fi;
339  while (!m_fragment_queue.empty()) {
340  fi = m_fragment_queue.front();
341  if (fi->revision < revision &&
342  (fi->remove_ok(remove_ok_logs) || !m_range_reference_required)) {
343  if (fi->references == 0) {
344  remove_file_info(fi, removed_logs);
345  delete fi;
346  }
347  else
348  m_reap_set.insert(fi);
349  m_fragment_queue.pop_front();
350  }
351  else {
352  string msg = format("purge(%s,rev=%llu) breaking on %s",
353  m_log_dir.c_str(), (Llu)revision,
354  fi->to_str(remove_ok_logs).c_str());
355  HT_INFOF("%s", msg.c_str());
356  if (trace)
357  *trace += msg + "\n";
358  break;
359  }
360  }
361 
362  return Error::OK;
363 }
364 
365 
367  string fname;
368 
369  fi->verify();
370 
371  // Remove linked log directores
372  for (const auto &logdir : fi->purge_dirs) {
373  try {
374  HT_INFOF("Removing linked log directory '%s' because all fragments have been removed", logdir.c_str());
375  removed_logs.insert(logdir);
376  m_fs->rmdir(logdir);
377  }
378  catch (Exception &e) {
379  HT_ERRORF("Problem removing log directory '%s' (%s - %s)",
380  logdir.c_str(), Error::get_text(e.code()), e.what());
381  }
382  }
383 
384  // Remove fragment file
385  try {
386  fname = fi->log_dir + "/" + fi->num;
387  HT_INFOF("Removing log fragment '%s' revision=%lld, parent=%lld",
388  fname.c_str(), (Lld)fi->revision, (Lld)fi->parent);
389  m_fs->remove(fname);
390  }
391  catch (Exception &e) {
392  if (e.code() != Error::FSBROKER_BAD_FILENAME &&
394  HT_ERRORF("Problem removing log fragment '%s' (%s - %s)",
395  fname.c_str(), Error::get_text(e.code()), e.what());
396  }
397 
398  // Decrement parent reference count
399  if (fi->parent) {
400  HT_ASSERT(fi->parent->references > 0);
401  fi->parent->references--;
402  }
403 
404 }
405 
407  CommitLogFileInfo *file_info;
408 
409  if (m_fd == -1)
410  return Error::CLOSED;
411 
413  return Error::OK;
414 
415  m_needs_roll = true;
416 
417  if (clfip)
418  *clfip = 0;
419 
420  if (m_fd >= 0) {
421  try {
422  m_fs->close(m_fd);
423  }
424  catch (Exception &e) {
425  HT_ERRORF("Problem closing commit log fragment: %s: %s",
426  m_cur_fragment_fname.c_str(), e.what());
427  return e.code();
428  }
429 
430  m_fd = -1;
431 
432  file_info = new CommitLogFileInfo();
433  if (clfip)
434  *clfip = file_info;
435  file_info->log_dir = m_log_dir;
436  file_info->log_dir_hash = md5_hash(m_log_dir.c_str());
437  file_info->num = m_cur_fragment_num;
438  file_info->size = m_cur_fragment_length;
439  assert(m_latest_revision != TIMESTAMP_MIN);
440  file_info->revision = m_latest_revision;
441 
442  if (m_fragment_queue.empty() || m_fragment_queue.back()->revision
443  < file_info->revision)
444  m_fragment_queue.push_back(file_info);
445  else {
446  m_fragment_queue.push_back(file_info);
447  struct LtClfip swo;
448  sort(m_fragment_queue.begin(), m_fragment_queue.end(), swo);
449  }
450 
452 
455 
456  }
457 
458  try {
460  -1, m_replication, -1);
463  }
464  catch (Exception &e) {
465  HT_ERRORF("Problem rolling commit log: %s: %s",
466  m_cur_fragment_fname.c_str(), e.what());
467  return e.code();
468  }
469 
470  m_needs_roll = false;
471 
472  return Error::OK;
473 }
474 
475 
476 int
478  int64_t revision, Filesystem::Flags flags) {
479  lock_guard<mutex> lock(m_mutex);
480  int error = Error::OK;
481  DynamicBuffer zblock;
482 
483  // Compress block and kick off log write (protected by lock)
484  try {
485 
486  if (m_fd == -1)
487  return Error::CLOSED;
488 
489  m_compressor->deflate(input, zblock, *header);
490 
491  size_t amount = zblock.fill();
492  StaticBuffer send_buf(zblock);
493 
494  m_fs->append(m_fd, send_buf, flags);
495  assert(revision != 0);
496  if (revision > m_latest_revision)
497  m_latest_revision = revision;
498  m_cur_fragment_length += amount;
499  }
500  catch (Exception &e) {
501  HT_ERRORF("Problem writing commit log: %s: %s",
502  m_cur_fragment_fname.c_str(), e.what());
503  error = e.code();
504  }
505 
506  return error;
507 }
508 
509 
511  lock_guard<mutex> lock(m_mutex);
512  int64_t cumulative_total = 0;
513  uint32_t distance = 0;
514  CumulativeFragmentData frag_data;
515 
516  if (m_fd == -1)
517  HT_THROWF(Error::CLOSED, "Commit log '%s' has been closed", m_log_dir.c_str());
518 
519  memset(&frag_data, 0, sizeof(frag_data));
520 
522  frag_data.size = m_cur_fragment_length;
523  frag_data.fragno = m_cur_fragment_num;
524  cumulative_size_map[m_latest_revision] = frag_data;
525  }
526 
527  for (std::deque<CommitLogFileInfo *>::reverse_iterator iter
528  = m_fragment_queue.rbegin(); iter != m_fragment_queue.rend(); ++iter) {
529  frag_data.size = (*iter)->size;
530  frag_data.fragno = (*iter)->num;
531  cumulative_size_map[(*iter)->revision] = frag_data;
532  }
533 
534  for (CumulativeSizeMap::reverse_iterator riter = cumulative_size_map.rbegin();
535  riter != cumulative_size_map.rend(); riter++) {
536  (*riter).second.distance = distance++;
537  cumulative_total += (*riter).second.size;
538  (*riter).second.cumulative_size = cumulative_total;
539  }
540 
541 }
542 
543 
544 void CommitLog::get_stats(const string &prefix, string &result) {
545  lock_guard<mutex> lock(m_mutex);
546 
547  if (m_fd == -1)
548  HT_THROWF(Error::CLOSED, "Commit log '%s' has been closed", m_log_dir.c_str());
549 
550  try {
551  for (const auto frag : m_fragment_queue) {
552  result += prefix + String("-log-fragment[") + frag->num + "]\tsize\t" + frag->size + "\n";
553  result += prefix + String("-log-fragment[") + frag->num + "]\trevision\t" + frag->revision + "\n";
554  result += prefix + String("-log-fragment[") + frag->num + "]\tdir\t" + frag->log_dir + "\n";
555  }
556  result += prefix + String("-log-fragment[") + m_cur_fragment_num + "]\tsize\t" + m_cur_fragment_length + "\n";
557  result += prefix + String("-log-fragment]") + m_cur_fragment_num + "]\trevision\t" + m_latest_revision + "\n";
558  result += prefix + String("-log-fragment]") + m_cur_fragment_num + "]\tdir\t" + m_log_dir + "\n";
559  }
560  catch (Hypertable::Exception &e) {
561  HT_ERROR_OUT << "Problem getting stats for log fragments" << HT_END;
562  HT_THROW(e.code(), e.what());
563  }
564 }
565 
std::set< String > StringSet
STL Set managing Strings.
Definition: StringExt.h:42
void set_data_length(uint32_t length)
Sets the uncompressed data length field.
Definition: BlockHeader.h:91
void stitch_in(CommitLogBase *other)
This method assumes that the other commit log is not being concurrently used which is why it doesn't ...
Definition: CommitLogBase.h:99
A memory buffer of static size.
Definition: StaticBuffer.h:45
void set_data_checksum(uint32_t checksum)
Sets the checksum field.
Definition: BlockHeader.h:113
#define HT_WARNF(msg,...)
Definition: Logger.h:290
static const char MAGIC_DATA[10]
Definition: CommitLog.h:199
std::map< int64_t, CumulativeFragmentData > CumulativeSizeMap
Definition: CommitLog.h:74
virtual size_t encoded_length()
Returns length of serizlized block header.
int64_t md5_hash(const char *input)
Returns a 64-bit hash checksum of a null terminated input buffer.
Definition: md5.cc:388
int write(uint64_t cluster_id, DynamicBuffer &buffer, int64_t revision, Filesystem::Flags flags)
Writes a block of updates to the commit log.
Definition: CommitLog.cc:181
void initialize(const std::string &log_dir, PropertiesPtr &, CommitLogBase *init_log, bool is_meta)
Definition: CommitLog.cc:70
PropertiesPtr properties
This singleton map stores all options.
Definition: Config.cc:47
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
String format(const char *fmt,...)
Returns a String using printf like format facilities Vanilla snprintf is about 1.5x faster than this...
Definition: String.cc:37
Declarations for CommitLogReader.
Flags
Enumeration type for append flags.
Definition: Filesystem.h:76
long long unsigned int Llu
Shortcut for printf formats.
Definition: String.h:50
void set_data_zlength(uint32_t zlength)
Sets the compressed data length field.
Definition: BlockHeader.h:101
std::string & get_log_dir()
STL namespace.
static void write_header(FilesystemPtr &fs, int32_t fd)
Writes commit log file header.
Declarations for BlockCompressionCodec.
uint8_t * ptr
Pointer to the end of the used part of the buffer.
A dynamic, resizable and reference counted memory buffer.
Definition: DynamicBuffer.h:42
static const int64_t TIMESTAMP_MIN
Definition: KeySpec.h:34
void load_cumulative_size_map(CumulativeSizeMap &cumulative_size_map)
Fills up a map of cumulative fragment size data.
Definition: CommitLog.cc:510
#define HT_ASSERT(_e_)
Definition: Logger.h:396
void set_revision(int64_t revision)
Sets the revision number field.
void get_stats(const std::string &prefix, std::string &result)
Returns the stats on all commit log fragments.
Definition: CommitLog.cc:544
uint32_t fletcher32(const void *data8, size_t len8)
Compute fletcher32 checksum for arbitary data.
Definition: Checksum.cc:42
File system utility functions.
LogFragmentQueue & fragment_queue()
A dynamic, resizable memory buffer.
int sync()
Sync previous updates written to commit log.
Definition: CommitLog.cc:161
int link_log(uint64_t cluster_id, CommitLogBase *log_base)
Links an external log into this log.
Definition: CommitLog.cc:211
static const char MAGIC_LINK[10]
Definition: CommitLog.h:200
virtual void encode(uint8_t **bufp)
Encodes commit log block header to memory location.
const char * get_text(int error)
Returns a descriptive error message.
Definition: Error.cc:330
uint8_t * add(const void *data, size_t len)
Adds more data WITH boundary checks; if required the buffer is resized and existing data is preserved...
std::shared_ptr< Properties > PropertiesPtr
Definition: Properties.h:447
Logging routines and macros.
virtual ~CommitLog()
Definition: CommitLog.cc:65
Compatibility Macros for C/C++.
int close()
Closes the log.
Definition: CommitLog.cc:290
#define HT_END
Definition: Logger.h:220
int64_t m_max_fragment_size
Definition: CommitLog.h:215
static BlockCompressionCodec * create_block_codec(BlockCompressionCodec::Type, const BlockCompressionCodec::Args &args=BlockCompressionCodec::Args())
Declarations for BlockHeaderCommitLog.
#define HT_ERROR_OUT
Definition: Logger.h:301
Time related declarations.
void remove_file_info(CommitLogFileInfo *fi, StringSet &removed_logs)
Definition: CommitLog.cc:366
int64_t m_cur_fragment_length
Definition: CommitLog.h:214
Hypertable definitions
long long int Lld
Shortcut for printf formats.
Definition: String.h:53
Implementation of checksum routines.
std::string to_str(StringSet &remove_ok_logs)
Definition: CommitLogBase.h:49
Helper class to access parts of the properties.
Definition: Properties.h:458
void set_compression_type(uint16_t type)
Sets the compression type field.
Definition: BlockHeader.h:123
std::shared_ptr< Filesystem > FilesystemPtr
Smart pointer to Filesystem.
Definition: Filesystem.h:572
bool remove_ok(StringSet &remove_ok_logs)
Definition: CommitLogBase.h:46
CommitLogFileInfo * parent
Definition: CommitLogBase.h:66
Declarations for Protocol.
#define HT_INFOF(msg,...)
Definition: Logger.h:272
#define HT_THROWF(_code_, _fmt_,...)
Definition: Error.h:490
static uint64_t header_size()
Size of header.
size_t fill() const
Returns the size of the used portion.
Definition: DynamicBuffer.h:70
std::string m_cur_fragment_fname
Definition: CommitLog.h:213
int flush()
Flushes previous updates written to commit log.
Definition: CommitLog.cc:143
This is a generic exception class for Hypertable.
Definition: Error.h:314
LogFragmentQueue m_fragment_queue
std::set< CommitLogFileInfo * > m_reap_set
Definition: CommitLog.h:211
#define HT_ERRORF(msg,...)
Definition: Logger.h:300
Declarations for CommitLog.
uint32_t m_cur_fragment_num
Definition: CommitLog.h:216
int64_t get_timestamp()
Atomically obtains a timestamp.
Definition: CommitLog.cc:139
Configuration settings.
std::set< int64_t > m_linked_log_hashes
int roll(CommitLogFileInfo **clfip=0)
Definition: CommitLog.cc:406
#define HT_TRY(_s_, _code_)
Definition: Error.h:517
Base class for block headers.
Definition: BlockHeader.h:48
std::unique_ptr< BlockCompressionCodec > m_compressor
Definition: CommitLog.h:212
String extensions and helpers: sets, maps, append operators etc.
Error codes, Exception handling, error logging.
#define HT_THROW(_code_, _msg_)
Definition: Error.h:478
md5 digest routines.
void ensure(size_t len)
Ensure space for additional data Will grow the space to 1.5 of the needed space with existing data un...
Definition: DynamicBuffer.h:82
int purge(int64_t revision, StringSet &remove_ok_logs, StringSet &removed_logs, std::string *trace)
Purges the log.
Definition: CommitLog.cc:310
int compress_and_write(DynamicBuffer &input, BlockHeader *header, int64_t revision, Filesystem::Flags flags)
Definition: CommitLog.cc:477
int64_t get_ts64()
Returns the current time in nanoseconds as a 64bit number.
Definition: Time.cc:40
FilesystemPtr m_fs
Definition: CommitLog.h:210
int code() const
Returns the error code.
Definition: Error.h:391
CommitLog(FilesystemPtr &fs, const std::string &log_dir, PropertiesPtr &props, CommitLogBase *init_log=0, bool is_meta=true)
Constructs a CommitLog object using supplied properties.
Definition: CommitLog.h:85