Example #1
0
 public SlaveIterator(FileMetaData file) {
   this.fileNumber = file.getNumber();
   // open the iterator
   this.iterator = tableCache.newIterator(file);
 }
Example #2
0
  private void readSst(
      String standby,
      int bucket,
      Position pos,
      int batchSize,
      Version v,
      FileQueue queue,
      Entrys entrys,
      boolean availableRollback,
      int deep) {
    // 防止调用超时,和栈溢出异常
    if (deep > 50) {
      return;
    }

    FileMetaData file = null;
    if (pos.fileNumber() < 0) {
      file = queue.poll();
    } else {
      file = queue.poll(pos.fileNumber());
    }

    // 当file为null时,意味着当前的version所有sst文件已经迁移完成,
    // 如果存在新的version,就切换到新的version,否则切换到log模式,开始去拉去log文件的数据
    if (file == null) {
      v.release();

      pos.switchToNew();
      Version snapshot = versions.getCurrent();
      if (v != snapshot) {
        v = snapshot;
        v.retain();
        pos.version(v.hashCode());
        pos.fileNumber(-1);
        readSst(
            standby,
            bucket,
            pos,
            batchSize,
            v,
            new FileQueue(bucket, v, pos.maxFileNumber()),
            entrys,
            availableRollback,
            ++deep);
      } else {
        // 日志模式不锁定version,只锁定log文件
        // log文件的锁定逻辑见DBImpl的logQ属性
        pos.fileNumber(log.getFileNumber());
        pos.pointer(0);
        pos.fileType(LOG);
      }

      return;
    } else {
      pos.fileNumber(file.getNumber());
    }

    // 读取大于maxSeq的记录
    String key = generateKey(standby, bucket);
    SlaveIterator si = v.iterators.get(key);
    if (si == null) {
      si = new SlaveIterator(file);
    } else {
      if (si.getFileNumber() != file.getNumber()) {
        si = new SlaveIterator(file);
      }
    }
    v.iterators.put(key, si);

    if (availableRollback) {
      if (pos.pointer() > 0) {
        logger.warn("{}-bucket sst happen rollback, position={}.", bucket, pos);
        si.seekToFirst();
      } else {
        pos.pointer(file.getNumber());
      }
    }

    long maxSeq = pos.maxSeq();
    while (si.hasNext()) {
      Entry<InternalKey, Slice> e = si.next(bucket, maxSeq);
      if (e != null) {
        InternalKey ikey = e.getKey();
        pos.curMaxSeq(ikey.getSequenceNumber());
        entrys.add(
            new BlockEntry(
                ikey.getUserKey(),
                ValueType.VALUE.equals(ikey.getValueType()) ? e.getValue() : Slices.EMPTY_SLICE));
      }
      if (entrys.size() > batchSize) {
        break;
      }
    }

    // 判断文件是否已经读取完成
    if (!si.hasNext()) {
      v.iterators.remove(key);
      FileMetaData fmd = queue.peek();
      if (fmd != null) {
        pos.fileNumber(fmd.getNumber());
      } else {
        pos.fileNumber(pos.curMaxFileNumber + 1); // +1意味着该version不存在该文件
      }
    }

    // 继续读取下一个文件的数据
    if (entrys.size() < batchSize) {
      readSst(standby, bucket, pos, batchSize, v, queue, entrys, false, ++deep);
    }
  }