@Override
 public void diskComponentAdded(final ILSMIndex index, boolean fullMergeIsRequested)
     throws HyracksDataException, IndexException {
   List<ILSMComponent> immutableComponents = index.getImmutableComponents();
   for (ILSMComponent c : immutableComponents) {
     if (c.getState() != ComponentState.READABLE_UNWRITABLE) {
       return;
     }
   }
   if (fullMergeIsRequested) {
     ILSMIndexAccessor accessor =
         (ILSMIndexAccessor)
             index.createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
     accessor.scheduleFullMerge(index.getIOOperationCallback());
   } else if (immutableComponents.size() >= numComponents) {
     ILSMIndexAccessor accessor =
         (ILSMIndexAccessor)
             index.createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
     accessor.scheduleMerge(index.getIOOperationCallback(), immutableComponents);
   }
 }
  @Override
  public void open(ICursorInitialState initialState, ISearchPredicate searchPred)
      throws HyracksDataException {
    LSMBTreeCursorInitialState lsmInitialState = (LSMBTreeCursorInitialState) initialState;
    operationalComponents = lsmInitialState.getOperationalComponents();
    lsmHarness = lsmInitialState.getLSMHarness();
    searchCallback = lsmInitialState.getSearchOperationCallback();
    predicate = (RangePredicate) lsmInitialState.getSearchPredicate();
    numBTrees = operationalComponents.size();
    if (rangeCursors == null || rangeCursors.length != numBTrees) {
      // object creation: should be relatively low
      rangeCursors = new BTreeRangeSearchCursor[numBTrees];
      btreeAccessors = new BTreeAccessor[numBTrees];
    }
    includeMutableComponent = false;

    for (int i = 0; i < numBTrees; i++) {
      ILSMComponent component = operationalComponents.get(i);
      BTree btree;
      if (component.getType() == LSMComponentType.MEMORY) {
        includeMutableComponent = true;
        // No need for a bloom filter for the in-memory BTree.
        if (rangeCursors[i] == null || rangeCursors[i].isBloomFilterAware()) {
          // create a new one
          IBTreeLeafFrame leafFrame =
              (IBTreeLeafFrame) lsmInitialState.getLeafFrameFactory().createFrame();
          rangeCursors[i] = new BTreeRangeSearchCursor(leafFrame, false);
        } else {
          // reset
          rangeCursors[i].reset();
        }
        btree = ((LSMBTreeMemoryComponent) component).getBTree();
      } else {
        if (rangeCursors[i] != null && rangeCursors[i].isBloomFilterAware()) {
          // can re-use cursor
          ((BloomFilterAwareBTreePointSearchCursor) rangeCursors[i])
              .resetBloomFilter(((LSMBTreeDiskComponent) component).getBloomFilter());
          rangeCursors[i].reset();
        } else {
          // create new cursor <should be relatively rare>
          IBTreeLeafFrame leafFrame =
              (IBTreeLeafFrame) lsmInitialState.getLeafFrameFactory().createFrame();
          rangeCursors[i] =
              new BloomFilterAwareBTreePointSearchCursor(
                  leafFrame, false, ((LSMBTreeDiskComponent) component).getBloomFilter());
        }
        btree = ((LSMBTreeDiskComponent) component).getBTree();
      }
      if (btreeAccessors[i] == null) {
        btreeAccessors[i] =
            (BTreeAccessor)
                btree.createAccessor(
                    NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
      } else {
        // re-use
        btreeAccessors[i].reset(
            btree, NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
      }
    }
    nextHasBeenCalled = false;
    foundTuple = false;
  }