Package com.alvazan.orm.layer9z.spi.db.cassandra

Source Code of com.alvazan.orm.layer9z.spi.db.cassandra.CursorColumnSlice

package com.alvazan.orm.layer9z.spi.db.cassandra;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.alvazan.orm.api.z8spi.BatchListener;
import com.alvazan.orm.api.z8spi.action.IndexColumn;
import com.alvazan.orm.api.z8spi.iter.AbstractCursor;
import com.alvazan.orm.api.z8spi.iter.StringLocal;
import com.alvazan.orm.layer9z.spi.db.cassandra.CassandraSession.CreateColumnSliceCallback;
import com.netflix.astyanax.connectionpool.OperationResult;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
import com.netflix.astyanax.model.Column;
import com.netflix.astyanax.model.ColumnList;
import com.netflix.astyanax.query.RowQuery;

class CursorColumnSlice<T> extends AbstractCursor<T> {

  private static String columnName;
  private CreateColumnSliceCallback callback;
  private boolean isComposite;
  private BatchListener batchListener;
  private Integer batchSize;

  private RowQuery<byte[], byte[]> query;
  private String info;
  private int pointer = -1;
  private List<Column<byte[]>> subList;
  private Boolean forward = null;
 
  public CursorColumnSlice(CreateColumnSliceCallback l, boolean isComposite, BatchListener bListener, Integer batchSize, String logInfo, String colName) {
    this.callback = l;
    this.isComposite = isComposite;
    this.batchListener = bListener;
    this.batchSize = batchSize;
    this.info = logInfo;
    this.columnName = colName;
    beforeFirst();
  }

  @Override
  public String toString() {
    String tabs = StringLocal.getAndAdd();
    String retVal = "CursorColumnSlice["+tabs+info+tabs+"]";
    StringLocal.set(tabs.length());
    return retVal;
  }
 
  @Override
  public void beforeFirst() {
    //FOR some reason in astyanax, we have to keep getting the row query on resets or this Cursor returns 5 rows instead of the
    //SAME two rows it returned the first time.....well, form one of the unit tests
     query = callback.createRowQuery();
     pointer = -1;
     subList = null;
     forward = true;
  }
 
  @Override
  public void afterLast() {
    //FOR some reason in astyanax, we have to keep getting the row query on resets or this Cursor returns 5 rows instead of the
    //SAME two rows it returned the first time.....well, form one of the unit tests
     query = callback.createRowQueryReverse();
     pointer = -1;
     subList = null;
     forward = false;
  }

  @Override
  public Holder<T> nextImpl() {
    if(!forward)
      throw new IllegalStateException("You must call beforeFirst to traverse the cursor forward, you cannot call next after calling previous due to limitations of talking to noSql apis");
    try {
      fetchMoreResultsImpl();
      pointer++;
      if(pointer >= subList.size())
        return null; //no more results
      Column<byte[]> column = subList.get(pointer);
     
      return buildHolder(column);
    } catch (ConnectionException e) {
      throw new RuntimeException(e);
    }
  }
 
  @Override
  public Holder<T> previousImpl() {
    if(forward)
      throw new IllegalStateException("You must call afterLast to traverse reverse.  You cannot call previous after calling next due to limitations of calling into noSQL apis");
    try {
      fetchMoreResultsImpl();
      pointer++;
      if(pointer >= subList.size())
        return null; //no more results
     
      Column<byte[]> column = subList.get(pointer);
      return buildHolder(column);
    } catch (ConnectionException e) {
      throw new RuntimeException(e);
    }
  }

  @SuppressWarnings("unchecked")
  private Holder<T> buildHolder(com.netflix.astyanax.model.Column<byte[]> col) {

    if(isComposite) {
      IndexColumn c = convertToIndexCol(col);
      return new Holder<T>((T) c);
    } else {
      Object obj = col.getName();
      com.alvazan.orm.api.z8spi.action.Column c = new com.alvazan.orm.api.z8spi.action.Column();
      byte[] name = (byte[])obj;
      c.setName(name);
      c.setValue(col.getByteArrayValue());
      c.setTimestamp(col.getTimestamp());
      return new Holder<T>((T) c);
    }
  }

  public static IndexColumn convertToIndexCol(com.netflix.astyanax.model.Column<byte[]> col) {
    Object colName = col.getName();
    GenericComposite bigDec = (GenericComposite)colName;
    IndexColumn c = new IndexColumn();
    c.setColumnName(columnName);
    c.setPrimaryKey(bigDec.getPk());
    c.setIndexedValue(bigDec.getIndexedValue());
    c.setValue(col.getByteArrayValue());
    return c;
  }
 
  private void fetchMoreResultsImpl() throws ConnectionException {
    if(subList != null){
      //If subIterator is not null, we have already previously fetched results!!!
      if(pointer < subList.size()-1)
        return; //no need to fetch next subiterator since this subIterator has more
      else if(batchSize == null) //then we already fetched everything in first round
        return;
      else if(subList.size() < batchSize) {
        //since we have previous results, we then have a count of those results BUT they
        //did NOT fill up the batch so no need to go to database as we know it has no more results
        return;
      }
    }
   
    //reset the point...
    pointer = -1;
   
    if(batchListener != null)
      batchListener.beforeFetchingNextBatch();
    OperationResult<ColumnList<byte[]>> opResult = query.execute();
    ColumnList<byte[]> columns = opResult.getResult();

    if(columns.isEmpty())
      subList = new ArrayList<Column<byte[]>>();
    else
      fillInList(columns);
   
    if(batchListener != null)
      batchListener.afterFetchingNextBatch(columns.size());
  }
 
  private void fillInList(ColumnList<byte[]> columns) {
    subList = new ArrayList<Column<byte[]>>();
    Iterator<Column<byte[]>> iter = columns.iterator();
    while(iter.hasNext()) {
      Column<byte[]> col = iter.next();
      subList.add(col);
    }
  }
}
TOP

Related Classes of com.alvazan.orm.layer9z.spi.db.cassandra.CursorColumnSlice

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.