Package org.apache.accumulo.core.iterators

Source Code of org.apache.accumulo.core.iterators.SourceSwitchingIterator$DataSource

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.accumulo.core.iterators;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.accumulo.core.data.ByteSequence;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.PartialKey;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.data.Value;

public class SourceSwitchingIterator implements SortedKeyValueIterator<Key,Value>, InterruptibleIterator {
 
  public interface DataSource {
    boolean isCurrent();
   
    DataSource getNewDataSource();
   
    DataSource getDeepCopyDataSource(IteratorEnvironment env);
   
    SortedKeyValueIterator<Key,Value> iterator() throws IOException;
  }
 
  private DataSource source;
  private SortedKeyValueIterator<Key,Value> iter;
 
  private Key key;
  private Value val;
 
  private Range range;
  private boolean inclusive;
  private Collection<ByteSequence> columnFamilies;
 
  private boolean onlySwitchAfterRow;
  private AtomicBoolean iflag;
 
  private List<SourceSwitchingIterator> copies;
 
  private SourceSwitchingIterator(DataSource source, boolean onlySwitchAfterRow, List<SourceSwitchingIterator> copies, AtomicBoolean iflag) {
    this.source = source;
    this.onlySwitchAfterRow = onlySwitchAfterRow;
    this.copies = copies;
    this.iflag = iflag;
    copies.add(this);
  }
 
  public SourceSwitchingIterator(DataSource source, boolean onlySwitchAfterRow) {
    this(source, onlySwitchAfterRow, Collections.synchronizedList(new ArrayList<SourceSwitchingIterator>()), null);
  }
 
  public SourceSwitchingIterator(DataSource source) {
    this(source, false);
  }
 
  @Override
  public SortedKeyValueIterator<Key,Value> deepCopy(IteratorEnvironment env) {
    return new SourceSwitchingIterator(source.getDeepCopyDataSource(env), onlySwitchAfterRow, copies, iflag);
  }
 
  @Override
  public Key getTopKey() {
    return key;
  }
 
  @Override
  public Value getTopValue() {
    return val;
  }
 
  @Override
  public boolean hasTop() {
    return key != null;
  }
 
  @Override
  public void init(SortedKeyValueIterator<Key,Value> source, Map<String,String> options, IteratorEnvironment env) throws IOException {
    throw new UnsupportedOperationException();
  }
 
  @Override
  public void next() throws IOException {
    readNext(false);
  }
 
  private synchronized void readNext(boolean initialSeek) throws IOException {
   
    // check of initialSeek second is intentional so that it does not short
    // circuit the call to switchSource
    boolean seekNeeded = (!onlySwitchAfterRow && switchSource()) || initialSeek;
   
    if (seekNeeded)
      if (initialSeek)
        iter.seek(range, columnFamilies, inclusive);
      else
        iter.seek(new Range(key, false, range.getEndKey(), range.isEndKeyInclusive()), columnFamilies, inclusive);
    else {
      iter.next();
      if (onlySwitchAfterRow && iter.hasTop() && !source.isCurrent() && !key.getRowData().equals(iter.getTopKey().getRowData())) {
        switchSource();
        iter.seek(new Range(key.followingKey(PartialKey.ROW), true, range.getEndKey(), range.isEndKeyInclusive()), columnFamilies, inclusive);
      }
    }
   
    if (iter.hasTop()) {
      Key nextKey = iter.getTopKey();
      Value nextVal = iter.getTopValue();
     
      key = (Key) nextKey.clone();
      val = nextVal;
    } else {
      key = null;
      val = null;
    }
  }
 
  private boolean switchSource() throws IOException {
    while (!source.isCurrent()) {
      source = source.getNewDataSource();
      iter = source.iterator();
      if (iflag != null)
        ((InterruptibleIterator) iter).setInterruptFlag(iflag);
     
      return true;
    }
   
    return false;
  }
 
  @Override
  public synchronized void seek(Range range, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException {
    this.range = range;
    this.inclusive = inclusive;
    this.columnFamilies = columnFamilies;
   
    if (iter == null) {
      iter = source.iterator();
      if (iflag != null)
        ((InterruptibleIterator) iter).setInterruptFlag(iflag);
    }
   
    readNext(true);
  }
 
  private synchronized void _switchNow() throws IOException {
    if (onlySwitchAfterRow)
      throw new IllegalStateException("Can only switch on row boundries");
   
    if (switchSource()) {
      if (key != null) {
        iter.seek(new Range(key, true, range.getEndKey(), range.isEndKeyInclusive()), columnFamilies, inclusive);
      }
    }
  }
 
  public void switchNow() throws IOException {
    synchronized (copies) {
      for (SourceSwitchingIterator ssi : copies)
        ssi._switchNow();
    }
  }
 
  @Override
  public synchronized void setInterruptFlag(AtomicBoolean flag) {
    if (copies.size() != 1)
      throw new IllegalStateException("setInterruptFlag() called after deep copies made " + copies.size());
   
    this.iflag = flag;
    if (iter != null)
      ((InterruptibleIterator) iter).setInterruptFlag(flag);
   
  }
 
}
TOP

Related Classes of org.apache.accumulo.core.iterators.SourceSwitchingIterator$DataSource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.