int smrlog_get_first_msg_offset (smrLog * handle, smrLogAddr * addr, int *found, int *off) { long long commit_seq; int offset; int ret; if (addr->seq == 0) { *found = 1; *off = 0; return 0; } offset = smrlog_get_offset (handle, addr); if (offset < 0) { return -1; } ret = find_commit_seq_msg (addr->addr, 0, offset, 1, found, off, &commit_seq); if (ret < 0) { return ret; } // More greedy if (*found && commit_seq >= addr->seq) { *off = (int) (commit_seq - addr->seq); } return 0; }
static int logical_recover (smrLog * handle, recoverState * rs) { long long seq; msgSeek seek; long long min_seq = rs->min_seq; long long max_seq = rs->max_seq; long long msg_min_seq = 0LL; long long msg_max_seq = 0LL; long long commit_max_seq = 0LL; smrLogAddr *addr = NULL; int from, to; int found = 0, roff; int ret; long long cseq; // check trivial case if (min_seq == max_seq) { assert (min_seq == 0LL); return 0; } /* * - find msg_min_seq, msg_max_seq * - find commit_max_seq */ for (seq = seq_round_down (min_seq); seq <= seq_round_down (max_seq); seq += SMR_LOG_FILE_DATA_SIZE) { from = 0; to = SMR_LOG_FILE_DATA_SIZE; addr = smrlog_read_mmap (handle, seq); if (addr == NULL) { ERRNO_POINT (); goto error; } if (seq <= min_seq) { from = min_seq - seq; } if (find_commit_seq_msg (addr->addr, from, to, 1, &found, &roff, &cseq) == -1) { ERRNO_POINT (); goto error; } smrlog_munmap (handle, addr); addr = NULL; if (found) { msg_min_seq = seq + roff; break; } } init_msg_seek (&seek); seek.limit = max_seq; /* -1 for the case where max_seq is end of the log file */ for (seq = seq_round_down (max_seq - 1); seq >= seq_round_down (min_seq); seq -= SMR_LOG_FILE_DATA_SIZE) { if (seek.idx < 0) { ERRNO_POINT (); goto error; } addr = smrlog_read_mmap (handle, seq); if (addr == NULL) { ERRNO_POINT (); goto error; } seek.addrs[seek.idx--] = addr; seek.begin = addr->seq; from = 0; if (seq + to > max_seq) { to = max_seq - seq; } else { to = SMR_LOG_FILE_DATA_SIZE; } ret = find_commit_seq_msg (addr->addr, from, to, 0, &found, &roff, &cseq); if (ret < 0) { ERRNO_POINT (); goto error; } if (found) { long long begin; commit_max_seq = cseq; begin = seq + roff + SMR_OP_SEQ_COMMITTED_SZ; ret = msg_seek_find_msg_end (&seek, begin, &msg_max_seq); if (ret < 0) { ERRNO_POINT (); goto error; } break; } } clear_msg_seek (handle, &seek); /* * check and adjust sequence numbers * 0 <= min_seq <= msg_min_seq <= commit_max_seq <= msg_max_seq <= max_seq */ if (min_seq > msg_min_seq || msg_min_seq > commit_max_seq || commit_max_seq > msg_max_seq || msg_max_seq > max_seq) { ERRNO_POINT (); goto error; } /* truncate to msg_max_seq */ ret = smrlog_purge_after (handle, msg_max_seq); if (ret < 0) { ERRNO_POINT (); goto error; } rs->msg_min_seq = msg_min_seq; rs->msg_max_seq = msg_max_seq; rs->commit_max_seq = commit_max_seq; return 0; error: if (addr != NULL) { smrlog_munmap (handle, addr); } clear_msg_seek (handle, &seek); return -1; }