Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 619 lines (525 sloc) 16.725 kb
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
3 #include "config.h"
4 #include <algorithm>
5
6 #include <sys/stat.h>
7
8 #include "mutation_log.hh"
9
10 extern "C" {
11 #include "crc32.h"
12 }
13
14 const char *mutation_log_type_names[] = {
15 "new", "del", "del_all", "commit1", "commit2", NULL
16 };
17
d8ec82e2 » trondn
2012-01-24 Retry interrupted system calls
18 static inline ssize_t doWrite(int fd, const uint8_t *buf, size_t nbytes) {
19 ssize_t ret;
20 while ((ret = write(fd, buf, nbytes)) == -1 && (errno == EINTR)) {
21 /* Retry */
22 }
23 return ret;
24 }
25
26 static inline int doClose(int fd) {
27 int ret;
28 while ((ret = close(fd)) == -1 && (errno == EINTR)) {
29 /* Retry */
30 }
31 return ret;
32 }
33
34 static inline int doFsync(int fd) {
35 int ret;
36 while ((ret = fsync(fd)) == -1 && (errno == EINTR)) {
37 /* Retry */
38 }
39 return ret;
40 }
41
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
42 static void writeFully(int fd, const uint8_t *buf, size_t nbytes) {
43 while (nbytes > 0) {
d8ec82e2 » trondn
2012-01-24 Retry interrupted system calls
44 ssize_t written = doWrite(fd, buf, nbytes);
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
45 assert(written >= 0);
46
47 nbytes -= written;
48 buf += written;
49 }
50 }
51
52 uint64_t MutationLogEntry::rowid() const {
53 return ntohll(_rowid);
54 }
55
56 MutationLog::MutationLog(const std::string &path,
57 const size_t bs)
58 : paddingHisto(GrowingWidthGenerator<uint32_t>(0, 8, 1.5), 32),
59 logPath(path),
60 blockSize(bs),
61 blockPos(HEADER_RESERVED),
62 file(-1),
63 entries(0),
64 entryBuffer(static_cast<uint8_t*>(calloc(MutationLogEntry::len(256), 1))),
65 blockBuffer(static_cast<uint8_t*>(calloc(bs, 1))),
66 syncConfig(DEFAULT_SYNC_CONF) {
67
68 assert(entryBuffer);
69 assert(blockBuffer);
70 if (logPath == "") {
71 file = DISABLED_FD;
72 }
73 }
74
75 MutationLog::~MutationLog() {
76 flush();
fa7330cf » chiyoung
2012-02-22 Log compactor that compacts a mutation log periodically.
77 close();
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
78 free(entryBuffer);
79 free(blockBuffer);
80 }
81
502e5ed9 » dustin
2012-01-27 Allow log warmup failures.
82 void MutationLog::disable() {
83 if (file >= 0) {
fa7330cf » chiyoung
2012-02-22 Log compactor that compacts a mutation log periodically.
84 close();
502e5ed9 » dustin
2012-01-27 Allow log warmup failures.
85 file = DISABLED_FD;
86 }
87 }
88
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
89 void MutationLog::newItem(uint16_t vbucket, const std::string &key, uint64_t rowid) {
2d711189 » dustin
2012-01-24 Short-circuit mutation_log public API when not isEnabled()
90 if (isEnabled()) {
91 MutationLogEntry *mle = MutationLogEntry::newEntry(entryBuffer,
92 rowid, ML_NEW, vbucket, key);
93 writeEntry(mle);
94 }
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
95 }
96
97 void MutationLog::delItem(uint16_t vbucket, const std::string &key) {
2d711189 » dustin
2012-01-24 Short-circuit mutation_log public API when not isEnabled()
98 if (isEnabled()) {
99 MutationLogEntry *mle = MutationLogEntry::newEntry(entryBuffer,
100 0, ML_DEL, vbucket, key);
101 writeEntry(mle);
102 }
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
103 }
104
105 void MutationLog::deleteAll(uint16_t vbucket) {
2d711189 » dustin
2012-01-24 Short-circuit mutation_log public API when not isEnabled()
106 if (isEnabled()) {
107 MutationLogEntry *mle = MutationLogEntry::newEntry(entryBuffer,
108 0, ML_DEL_ALL, vbucket, "");
109 writeEntry(mle);
110 }
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
111 }
112
4dcc7fb5 » dustin
2012-01-27 Reusable mutation log sync.
113 void MutationLog::sync() {
a71b32a9 » dustin
2012-01-27 Separate log instantiation from file opening.
114 assert(isOpen());
4dcc7fb5 » dustin
2012-01-27 Reusable mutation log sync.
115 BlockTimer timer(&syncTimeHisto);
116 int fsyncResult = doFsync(file);
117 assert(fsyncResult != -1);
118 }
119
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
120 void MutationLog::commit1() {
2d711189 » dustin
2012-01-24 Short-circuit mutation_log public API when not isEnabled()
121 if (isEnabled()) {
122 MutationLogEntry *mle = MutationLogEntry::newEntry(entryBuffer,
123 0, ML_COMMIT1, 0, "");
124 writeEntry(mle);
125 if ((getSyncConfig() & FLUSH_COMMIT_1) != 0) {
126 flush();
127 }
128 if ((getSyncConfig() & SYNC_COMMIT_1) != 0) {
4dcc7fb5 » dustin
2012-01-27 Reusable mutation log sync.
129 sync();
2d711189 » dustin
2012-01-24 Short-circuit mutation_log public API when not isEnabled()
130 }
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
131 }
132 }
133
134 void MutationLog::commit2() {
2d711189 » dustin
2012-01-24 Short-circuit mutation_log public API when not isEnabled()
135 if (isEnabled()) {
136 MutationLogEntry *mle = MutationLogEntry::newEntry(entryBuffer,
137 0, ML_COMMIT2, 0, "");
138 writeEntry(mle);
139 if ((getSyncConfig() & FLUSH_COMMIT_2) != 0) {
140 flush();
141 }
142 if ((getSyncConfig() & SYNC_COMMIT_2) != 0) {
4dcc7fb5 » dustin
2012-01-27 Reusable mutation log sync.
143 sync();
2d711189 » dustin
2012-01-24 Short-circuit mutation_log public API when not isEnabled()
144 }
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
145 }
146 }
147
148 void MutationLog::writeInitialBlock() {
149 assert(isEnabled());
a71b32a9 » dustin
2012-01-27 Separate log instantiation from file opening.
150 assert(isOpen());
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
151 headerBlock.set(blockSize);
152
153 writeFully(file, (uint8_t*)&headerBlock, sizeof(headerBlock));
154
155 int lseek_result = lseek(file, std::max(static_cast<uint32_t>(MIN_LOG_HEADER_SIZE),
156 headerBlock.blockSize() * headerBlock.blockCount())
157 - 1, SEEK_SET);
158 assert(lseek_result > 0);
159 uint8_t zero(0);
160 writeFully(file, &zero, sizeof(zero));
161 }
162
163 void MutationLog::readInitialBlock() {
a71b32a9 » dustin
2012-01-27 Separate log instantiation from file opening.
164 assert(isOpen());
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
165 uint8_t buf[MIN_LOG_HEADER_SIZE];
166 ssize_t bytesread = pread(file, buf, sizeof(buf), 0);
167 assert(bytesread == sizeof(buf));
168
169 headerBlock.set(buf, sizeof(buf));
170
54e21b95 » dustin
2012-01-27 Handle short reads and invalid CRCs in log reading.
171 // These are reserved for future use.
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
172 assert(headerBlock.version() == LOG_VERSION);
173 assert(headerBlock.blockCount() == 1);
174
175 blockSize = headerBlock.blockSize();
176 }
177
178 void MutationLog::prepareWrites() {
179 if (isEnabled()) {
a71b32a9 » dustin
2012-01-27 Separate log instantiation from file opening.
180 assert(isOpen());
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
181 int lseek_result = lseek(file, 0, SEEK_END);
182 assert(lseek_result > 0);
54e21b95 » dustin
2012-01-27 Handle short reads and invalid CRCs in log reading.
183 if (lseek_result % blockSize != 0) {
184 throw ShortReadException();
185 }
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
186 logSize = static_cast<size_t>(lseek_result);
187 }
188 }
189
190 static uint8_t parseConfigString(const std::string &s) {
191 uint8_t rv(0);
192 if (s == "off") {
193 rv = 0;
194 } else if (s == "commit1") {
195 rv = 1;
196 } else if (s == "commit2") {
197 rv = 2;
198 } else if (s == "full") {
199 rv = 3;
200 } else {
201 rv = 0xff;
202 }
203 return rv;
204 }
205
206 bool MutationLog::setSyncConfig(const std::string &s) {
207 uint8_t v(parseConfigString(s));
208 if (v != 0xff) {
209 syncConfig = (syncConfig & ~SYNC_FULL) | v;
210 }
211 return v != 0xff;
212 }
213
214 bool MutationLog::setFlushConfig(const std::string &s) {
215 uint8_t v(parseConfigString(s));
216 if (v != 0xff) {
217 syncConfig = (syncConfig & ~FLUSH_FULL) | (v << 2);
218 }
219 return v != 0xff;
220 }
221
f8a1bdb8 » trondn
2012-02-20 Improve error handling for reading mutation log
222 bool MutationLog::exists() const {
223 return access(logPath.c_str(), F_OK) == 0;
224 }
225
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
226 void MutationLog::open() {
227 if (!isEnabled()) {
228 return;
229 }
230 file = ::open(const_cast<char*>(logPath.c_str()), O_RDWR|O_CREAT, 0666);
54e21b95 » dustin
2012-01-27 Handle short reads and invalid CRCs in log reading.
231 if (file < 0) {
232 std::stringstream ss;
233 ss << "Unable to open log file: " << strerror(errno);
234 throw ReadException(ss.str());
235 }
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
236 struct stat st;
237 int stat_result = fstat(file, &st);
238 assert(stat_result == 0);
239
54e21b95 » dustin
2012-01-27 Handle short reads and invalid CRCs in log reading.
240 if (st.st_size > 0 && st.st_size < static_cast<off_t>(blockSize)) {
fa7330cf » chiyoung
2012-02-22 Log compactor that compacts a mutation log periodically.
241 close();
54e21b95 » dustin
2012-01-27 Handle short reads and invalid CRCs in log reading.
242 file = DISABLED_FD;
243 throw ShortReadException();
244 }
245
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
246 if (st.st_size > 0) {
247 readInitialBlock();
248 } else {
249 writeInitialBlock();
250 }
251
252 prepareWrites();
a71b32a9 » dustin
2012-01-27 Separate log instantiation from file opening.
253 assert(isOpen());
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
254 }
255
fa7330cf » chiyoung
2012-02-22 Log compactor that compacts a mutation log periodically.
256 void MutationLog::close() {
257 if (!isEnabled()) {
258 return;
259 }
260
261 if (file >= 0) {
262 int close_result = doClose(file);
263 assert(close_result != -1);
264 file = -1;
265 }
266 }
267
268 bool MutationLog::replaceWith(MutationLog &mlog) {
269 assert(mlog.isEnabled());
270 assert(isEnabled());
271
272 mlog.flush();
273 mlog.close();
274 flush();
275 close();
276
277 for (int i(0); i < MUTATION_LOG_TYPES; ++i) {
278 itemsLogged[i] = mlog.itemsLogged[i];
279 }
280
281 if (rename(mlog.getLogFile().c_str(), getLogFile().c_str()) != 0) {
282 open();
283 std::stringstream ss;
284 ss << "Unable to rename a mutation log \"" << mlog.getLogFile() << "\" "
285 << "to \"" << getLogFile() << "\": " << strerror(errno);
286 getLogger()->log(EXTENSION_LOG_WARNING, NULL,
287 "%s!!! Reopened the old log file.\n", ss.str().c_str());
288 return false;
289 }
290
291 open();
292 getLogger()->log(EXTENSION_LOG_INFO, NULL,
293 "Renamed a mutation log \"%s\" to \"%s\" and reopened it.\n",
294 mlog.getLogFile().c_str(), getLogFile().c_str());
295 return true;
296 }
297
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
298 void MutationLog::flush() {
299 if (isEnabled() && blockPos > HEADER_RESERVED) {
a71b32a9 » dustin
2012-01-27 Separate log instantiation from file opening.
300 assert(isOpen());
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
301 BlockTimer timer(&flushTimeHisto);
302
303 if (blockPos < blockSize) {
304 size_t padding(blockSize - blockPos);
305 memset(blockBuffer + blockPos, 0x00, padding);
306 paddingHisto.add(padding);
307 }
308
309 entries = htons(entries);
310 memcpy(blockBuffer + 2, &entries, sizeof(entries));
311
312 uint32_t crc32(crc32buf(blockBuffer + 2, blockSize - 2));
313 uint16_t crc16(htons(crc32 & 0xffff));
314 memcpy(blockBuffer, &crc16, sizeof(crc16));
315
316 writeFully(file, blockBuffer, blockSize);
317 logSize += blockSize;
318
319 blockPos = HEADER_RESERVED;
320 entries = 0;
321 }
322 }
323
324 void MutationLog::writeEntry(MutationLogEntry *mle) {
2d711189 » dustin
2012-01-24 Short-circuit mutation_log public API when not isEnabled()
325 assert(isEnabled());
a71b32a9 » dustin
2012-01-27 Separate log instantiation from file opening.
326 assert(isOpen());
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
327 size_t len(mle->len());
328 if (blockPos + len > blockSize) {
329 flush();
330 }
331 assert(len < blockSize);
332
333 memcpy(blockBuffer + blockPos, mle, len);
334 blockPos += len;
335 ++entries;
336
337 ++itemsLogged[mle->type()];
338
339 delete mle;
340 }
341
342 static const char* logType(uint8_t t) {
343 switch(t) {
344 case ML_NEW:
345 return "new";
346 break;
347 case ML_DEL:
348 return "del";
349 break;
350 case ML_DEL_ALL:
351 return "delall";
352 break;
353 case ML_COMMIT1:
354 return "commit1";
355 break;
356 case ML_COMMIT2:
357 return "commit2";
358 break;
359 }
360 return "UNKNOWN";
361 }
362
363 // ----------------------------------------------------------------------
364 // Mutation log iterator
365 // ----------------------------------------------------------------------
366
367 MutationLog::iterator::iterator(const MutationLog *l, bool e)
368 : log(l),
369 entryBuf(NULL),
370 buf(NULL),
371 p(buf),
372 offset(l->header().blockSize() * l->header().blockCount()),
373 items(0), isEnd(e) {
374
375 assert(log);
376 }
377
378 MutationLog::iterator::iterator(const MutationLog::iterator& mit)
379 : log(mit.log),
380 entryBuf(NULL),
381 buf(NULL),
382 p(NULL),
383 offset(mit.offset),
384 items(0),
385 isEnd(mit.isEnd) {
386
387 assert(log);
388 if (mit.buf != NULL) {
389 buf = static_cast<uint8_t*>(calloc(1, log->header().blockSize()));
390 assert(buf);
391 memcpy(buf, mit.buf, log->header().blockSize());
392 p = buf + (mit.p - mit.buf);
393 }
394 if (mit.entryBuf != NULL) {
395 buf = static_cast<uint8_t*>(calloc(1, LOG_ENTRY_BUF_SIZE));
396 assert(entryBuf);
397 memcpy(entryBuf, mit.entryBuf, LOG_ENTRY_BUF_SIZE);
398 }
399 }
400
401 MutationLog::iterator::~iterator() {
402 free(entryBuf);
403 free(buf);
404 }
405
406 void MutationLog::iterator::prepItem() {
407 MutationLogEntry *e = MutationLogEntry::newEntry(p, bufferBytesRemaining());
408 if (entryBuf == NULL) {
409 entryBuf = static_cast<uint8_t*>(calloc(1, LOG_ENTRY_BUF_SIZE));
410 assert(entryBuf);
411 }
412 memcpy(entryBuf, p, e->len());
413 }
414
415 MutationLog::iterator& MutationLog::iterator::operator++() {
416 if (--items == 0) {
417 nextBlock();
418 } else {
419 size_t l(operator*()->len());
420 p += l;
421
422 prepItem();
423 }
424 return *this;
425 }
426
427 MutationLog::iterator& MutationLog::iterator::operator++(int) {
428 abort();
429 return *this;
430 }
431
432 bool MutationLog::iterator::operator==(const MutationLog::iterator& rhs) {
433 return log->fd() == rhs.log->fd()
434 && (
435 (isEnd == rhs.isEnd)
436 || (offset == rhs.offset
437 && items == rhs.items));
438 }
439
440 bool MutationLog::iterator::operator!=(const MutationLog::iterator& rhs) {
441 return ! operator==(rhs);
442 }
443
444 const MutationLogEntry* MutationLog::iterator::operator*() {
445 assert(entryBuf != NULL);
446 return MutationLogEntry::newEntry(entryBuf, LOG_ENTRY_BUF_SIZE);
447 }
448
449 size_t MutationLog::iterator::bufferBytesRemaining() {
450 return log->header().blockSize() - (p - buf);
451 }
452
453 void MutationLog::iterator::nextBlock() {
a71b32a9 » dustin
2012-01-27 Separate log instantiation from file opening.
454 assert(!log->isEnabled() || log->isOpen());
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
455 if (buf == NULL) {
456 buf = static_cast<uint8_t*>(calloc(1, log->header().blockSize()));
457 assert(buf);
458 }
54e21b95 » dustin
2012-01-27 Handle short reads and invalid CRCs in log reading.
459 p = buf;
460
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
461 ssize_t bytesread = pread(log->fd(), buf, log->header().blockSize(), offset);
54e21b95 » dustin
2012-01-27 Handle short reads and invalid CRCs in log reading.
462 if (bytesread < 1) {
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
463 isEnd = true;
464 return;
465 }
54e21b95 » dustin
2012-01-27 Handle short reads and invalid CRCs in log reading.
466 if (bytesread != (ssize_t)(log->header().blockSize())) {
467 throw ShortReadException();
468 }
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
469 offset += bytesread;
470
471 uint32_t crc32(crc32buf(buf + 2, log->header().blockSize() - 2));
472 uint16_t computed_crc16(crc32 & 0xffff);
473 uint16_t retrieved_crc16;
474 memcpy(&retrieved_crc16, buf, sizeof(retrieved_crc16));
475 retrieved_crc16 = ntohs(retrieved_crc16);
54e21b95 » dustin
2012-01-27 Handle short reads and invalid CRCs in log reading.
476 if (computed_crc16 != retrieved_crc16) {
477 throw CRCReadException();
478 }
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
479
480 memcpy(&items, buf + 2, 2);
481 items = ntohs(items);
482
483 p = p + 4;
484
485 prepItem();
486 }
487
488 void MutationLog::resetCounts(size_t *items) {
489 for (int i(0); i < MUTATION_LOG_TYPES; ++i) {
490 itemsLogged[i] = items[i];
491 }
492 }
493
494 // ----------------------------------------------------------------------
495 // Reading entries
496 // ----------------------------------------------------------------------
497
498 bool MutationLogHarvester::load() {
499 bool clean(false);
500 std::set<uint16_t> shouldClear;
501 for (MutationLog::iterator it(mlog.begin()); it != mlog.end(); ++it) {
502 const MutationLogEntry *le = *it;
503 ++itemsSeen[le->type()];
504 clean = false;
505
506 switch (le->type()) {
507 case ML_DEL:
508 // FALLTHROUGH
509 case ML_NEW:
510 if (vbid_set.find(le->vbucket()) != vbid_set.end()) {
511 loading[le->vbucket()][le->key()] = std::make_pair(le->rowid(), le->type());
512 }
513 break;
514 case ML_COMMIT2: {
515 clean = true;
516 for (std::set<uint16_t>::iterator vit(shouldClear.begin()); vit != shouldClear.end(); ++vit) {
517 committed[*vit].clear();
518 }
519 shouldClear.clear();
520
521 for (std::set<uint16_t>::const_iterator vit = vbid_set.begin(); vit != vbid_set.end(); ++vit) {
522 uint16_t vb(*vit);
523
524 unordered_map<std::string, mutation_log_event_t>::iterator copyit2;
525 for (copyit2 = loading[vb].begin();
526 copyit2 != loading[vb].end();
527 ++copyit2) {
528
529 mutation_log_event_t t = copyit2->second;
530
531 switch (t.second) {
532 case ML_NEW:
533 committed[vb][copyit2->first] = t.first;
534 break;
535 case ML_DEL:
536 committed[vb].erase(copyit2->first);
537 break;
538 default:
539 abort();
540 }
541 }
542 }
543 }
544 loading.clear();
545 break;
546 case ML_COMMIT1:
547 // nothing in particular
548 break;
549 case ML_DEL_ALL:
550 if (vbid_set.find(le->vbucket()) != vbid_set.end()) {
551 loading[le->vbucket()].clear();
552 shouldClear.insert(le->vbucket());
553 }
554 break;
555 default:
556 abort();
557 }
558 }
559 return clean;
560 }
561
562 void MutationLogHarvester::apply(void *arg, mlCallback mlc) {
563 for (std::set<uint16_t>::const_iterator it = vbid_set.begin();
564 it != vbid_set.end(); ++it) {
565 uint16_t vb(*it);
566
567 for (unordered_map<std::string, uint64_t>::iterator it2 = committed[vb].begin();
568 it2 != committed[vb].end(); ++it2) {
569 const std::string key(it2->first);
570 uint64_t rowid(it2->second);
571
572 mlc(arg, vb, vbids[vb], key, rowid);
573 }
574 }
575 }
576
0375877c » chiyoung
2012-02-23 Delete uncommitted log items from hash table and data store.
577 void MutationLogHarvester::getUncommitted(std::vector<mutation_log_uncommitted_t> &uitems) {
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
578
579 for (std::set<uint16_t>::const_iterator vit = vbid_set.begin(); vit != vbid_set.end(); ++vit) {
580 uint16_t vb(*vit);
581 mutation_log_uncommitted_t leftover;
582 leftover.vbucket = vb;
583
584 unordered_map<std::string, mutation_log_event_t>::iterator copyit2;
585 for (copyit2 = loading[vb].begin();
586 copyit2 != loading[vb].end();
587 ++copyit2) {
588
589 mutation_log_event_t t = copyit2->second;
590 leftover.key = copyit2->first;
591 leftover.rowid = t.first;
592 leftover.type = static_cast<mutation_log_type_t>(t.second);
593
0375877c » chiyoung
2012-02-23 Delete uncommitted log items from hash table and data store.
594 uitems.push_back(leftover);
b7075ce6 » dustin
2011-12-19 Log major key events to be able to quickly recover HT state.
595 }
596 }
597 }
598
599 size_t MutationLogHarvester::total() {
600 size_t rv(0);
601 for (int i = 0; i < MUTATION_LOG_TYPES; ++i) {
602 rv += itemsSeen[i];
603 }
604 return rv;
605 }
606
607 // ----------------------------------------------------------------------
608 // Output of entries
609 // ----------------------------------------------------------------------
610
611 std::ostream& operator <<(std::ostream &out, const MutationLogEntry &mle) {
612 out << "{MutationLogEntry rowid=" << mle.rowid()
613 << ", vbucket=" << mle.vbucket()
614 << ", magic=0x" << std::hex << static_cast<uint16_t>(mle.magic)
615 << std::dec
616 << ", type=" << logType(mle.type())
617 << ", key=``" << mle.key() << "''";
618 return out;
619 }
Something went wrong with that request. Please try again.