Exemple #1
0
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;
}
Exemple #2
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;
}