public SSTableSliceIterator(
      SSTableReader ssTable, String key, byte[] startColumn, byte[] finishColumn, boolean reversed)
      throws IOException {
    this.reversed = reversed;

    /* Morph key into actual key based on the partition type. */
    DecoratedKey decoratedKey = ssTable.getPartitioner().decorateKey(key);
    FileDataInput fdi =
        ssTable.getFileDataInput(
            decoratedKey, DatabaseDescriptor.getSlicedReadBufferSizeInKB() * 1024);
    this.comparator = ssTable.getColumnComparator();
    this.startColumn = startColumn;
    this.finishColumn = finishColumn;
    if (fdi != null) {
      // BIGDATA: move up here
      DecoratedKey keyInDisk = ssTable.getPartitioner().convertFromDiskFormat(fdi.readUTF());
      assert keyInDisk.equals(decoratedKey)
          : String.format("%s != %s in %s", keyInDisk, decoratedKey, fdi.getPath());

      dataSize = fdi.readInt(); // row data size
      dataStart = fdi.getAbsolutePosition();
      rowFormat = ColumnFamily.serializer().deserializeRowFormat(fdi);
      realDataStart = fdi.getAbsolutePosition();

      // !BIGDATA: branch out to the different code process for new rowformat/compression.
      if (ColumnFamily.serializer().isNewRowFormat(rowFormat)) {
        // new row format
        reader = new BigdataColumnGroupReader(ssTable, decoratedKey, fdi);
      } else {
        // old row format
        reader = new ColumnGroupReader(ssTable, decoratedKey, fdi);
      }
    }
  }
 // BIGDATA: new serializeWithIndexes, to support old and new row format
 public void serializeWithIndexes(
     ColumnFamily columnFamily,
     DataOutputBuffer headerDos,
     DataOutputBuffer dos,
     Compression.Algorithm compressAlgo) {
   if ((compressAlgo != null)
       && ((DatabaseDescriptor.getCompressStartRowSize() <= 0)
           || columnFamily.isSizeLargeThan(DatabaseDescriptor.getCompressStartRowSize()))) {
     boolean newIndexAtEnd = DatabaseDescriptor.isNewRowFormatIndexAtEnd();
     // use the id of compressAlgo
     serializeRowFormat(true, newIndexAtEnd, compressAlgo.getId(), headerDos);
     if (newIndexAtEnd) bigdataSerializeWithIndexesAtEnd(columnFamily, dos, compressAlgo);
     else bigdataSerializeWithIndexes(columnFamily, headerDos, dos, compressAlgo);
   } else {
     serializeRowFormat(false, false, 0, headerDos);
     oldSerializeWithIndexes(columnFamily, dos);
   }
 }
 public void saveRowCache() throws IOException {
   Function<String, byte[]> function =
       new Function<String, byte[]>() {
         public byte[] apply(String key) {
           return key.getBytes(Charset.forName("UTF-8"));
         }
       };
   CacheWriter<String, ColumnFamily> writer = new CacheWriter<String, ColumnFamily>();
   writer.saveCache(
       rowCache, DatabaseDescriptor.getSerializedRowCachePath(ksname, cfname), function);
 }
 public void saveKeyCache() throws IOException {
   Function<Pair<String, DecoratedKey>, byte[]> function =
       new Function<Pair<String, DecoratedKey>, byte[]>() {
         public byte[] apply(Pair<String, DecoratedKey> key) {
           return key.right.key.getBytes(Charset.forName("UTF-8"));
         }
       };
   CacheWriter<Pair<String, DecoratedKey>, SSTable.PositionSize> writer =
       new CacheWriter<Pair<String, DecoratedKey>, SSTable.PositionSize>();
   writer.saveCache(
       keyCache, DatabaseDescriptor.getSerializedKeyCachePath(ksname, cfname), function);
 }
  /** Resizes the key and row caches based on the current key estimate. */
  public synchronized void updateCacheSizes() {
    long keys = estimatedKeys();

    if (!keyCache.isCapacitySetManually()) {
      int keyCacheSize = DatabaseDescriptor.getKeysCachedFor(ksname, cfname, keys);
      if (keyCacheSize != keyCache.getCapacity()) {
        // update cache size for the new key volume
        if (logger.isDebugEnabled())
          logger.debug("key cache capacity for " + cfname + " is " + keyCacheSize);
        keyCache.updateCapacity(keyCacheSize);
      }
    }

    if (!rowCache.isCapacitySetManually()) {
      int rowCacheSize = DatabaseDescriptor.getRowsCachedFor(ksname, cfname, keys);
      if (rowCacheSize != rowCache.getCapacity()) {
        if (logger.isDebugEnabled())
          logger.debug("row cache capacity for " + cfname + " is " + rowCacheSize);
        rowCache.updateCapacity(rowCacheSize);
      }
    }
  }
  /**
   * !BIGDATA: ************************************************************************ New
   * serialized ColumnFamily row with column index. The new method to write column family row
   * (column index and columns) to SSTable.
   * ************************************************************************
   *
   * <p>the new format of ColumnFamily row: |------------------------| | bloom filter | (int for
   * len, and content) |------------------------| | deletion meta | localDeletionTime(int) and
   * markedForDeleteAt(long) |------------------------| | column count | (int)
   * |------------------------|<-------|<---- COLUMN BLOCKS START POSITION(CBSP) | column block 0 |
   * | BLOCK-INDEX OFFSET FROM CBSP | (compressed) | | |---------- ----------|<---| | | column block
   * 1 | | | | (compressed) | | | |------------------------|<---|---|------| | column index size | |
   * | | (byte size of column index) |------------------------| | | | | index of block 0 |----|----
   * | |---------- ----------| | | | index of block 1 |----- | |------------------------| | | index
   * size |---------------- to seek to position of index |------------------------|
   *
   * @param columnFamily
   * @param dos
   * @throws IOException
   */
  public void bigdataSerializeWithIndexesAtEnd(
      ColumnFamily columnFamily, DataOutputBuffer dos, Compression.Algorithm compressAlgo) {
    // get the sorted columns from column family row
    Collection<IColumn> columns = columnFamily.getSortedColumns();

    // create and serialize bloom filter
    BigdataColumnIndexer.createAndSerializeBloomFiliter(columns, dos);

    /*
     * Maintains a list of Column IndexInfo objects for the columns in this
     * column family row. The key is the column name and the position is the
     * relative offset of that column name from the start of the list.
     * We do this so that we don't read all the columns into memory.
     */
    List<IndexHelper.IndexInfo> indexList = new ArrayList<IndexHelper.IndexInfo>();

    // different column family use different compression algorithm.
    CompressionContext context = CompressionContext.getInstance(compressAlgo);

    try {
      // deletion meta information
      dos.writeInt(columnFamily.localDeletionTime.get());
      dos.writeLong(columnFamily.markedForDeleteAt.get());

      // column count
      dos.writeInt(columns.size());

      // the current column
      IColumn column = null;
      // the size of serialized column index, computed up front
      int indexSizeInBytes = 0;
      // the position of first block, at where the column blocks start.
      int firstBlockPos = dos.getLength();
      // the first column of current block
      IColumn blockFirstColumn = null;
      // the start position of current block
      // the column index will store the offset from firstBlockPos
      int blockStartPos = firstBlockPos;
      // uncompressed current block size
      int blockSize = 0;
      // compressed output stream of current block
      DataOutputStream blockOut = null;

      for (Iterator<IColumn> it = columns.iterator(); it.hasNext(); ) {
        column = it.next();

        if ((blockFirstColumn == null) && (blockOut == null)) {
          // start a new block
          blockFirstColumn = column;
          blockStartPos = dos.getLength();
          blockSize = 0;
          // get a new block output stream
          blockOut = getBlockOutputStream(dos, context);
        }

        // serialize column
        columnFamily.getColumnSerializer().serialize(column, blockOut);
        // uncompressed block size
        blockSize += column.serializedSize();

        // if we hit the block size that we have to index after, go ahead and index it.
        if (blockSize >= DatabaseDescriptor.getColumnIndexSize()) {
          int blockWidth = releaseBlockOutputStream(blockOut, context);
          assert blockWidth == blockSize;
          blockOut = null;

          int blockEndPos = dos.getLength();
          IndexHelper.IndexInfo cIndexInfo =
              new IndexHelper.IndexInfo(
                  blockFirstColumn.name(),
                  column.name(),
                  blockStartPos - firstBlockPos,
                  blockWidth,
                  blockEndPos - blockStartPos);
          indexList.add(cIndexInfo);
          indexSizeInBytes += cIndexInfo.serializedSize();

          // to next block
          blockFirstColumn = null;
        }
      }

      if (blockOut != null) {
        int blockWidth = releaseBlockOutputStream(blockOut, context);
        assert blockWidth == blockSize;
        blockOut = null;

        int blockEndPos = dos.getLength();
        IndexHelper.IndexInfo cIndexInfo =
            new IndexHelper.IndexInfo(
                blockFirstColumn.name(),
                column.name(),
                blockStartPos - firstBlockPos,
                blockWidth,
                blockEndPos - blockStartPos);
        indexList.add(cIndexInfo);
        indexSizeInBytes += cIndexInfo.serializedSize();
      }

      // the start position of column index
      int indexStartPos = dos.getLength();
      // serialize column index
      BigdataColumnIndexer.serialize(indexList, indexSizeInBytes, dos);
      // write out the size of index.
      dos.writeInt(dos.getLength() - indexStartPos);
    } catch (IOException e) {
      logger.error(e.toString());
      throw new RuntimeException(e);
    } finally {
      context.releaseCompressor();
    }
  }