/* (c) 2014 LinkedIn Corp. All rights reserved. * * Licensed 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. */ package com.linkedin.cubert.block; import org.apache.pig.data.Tuple; import org.codehaus.jackson.JsonNode; import java.io.IOException; /** * Creates subblocks pivoted by the number of rows. * <p/> * This class does not clone any tuple, and it works correctly if the source block is reusing tuples. * * @author Maneesh Varshney */ public class RowPivotedBlock implements Block { private final Block block; private final long rowCount; private long remaining; private Tuple firstTuple = null; private boolean finished = false; public RowPivotedBlock(Block block, long rowCount) throws IOException, InterruptedException { this.block = block; this.rowCount = rowCount; this.remaining = rowCount; this.firstTuple = block.next(); } @Override public void configure(JsonNode json) throws IOException, InterruptedException { } @Override public BlockProperties getProperties() { return block.getProperties(); } public Tuple next() throws IOException, InterruptedException { // if we have generated the specified count of tuple, this block is finished. if (remaining == 0) { return null; } // get the next tuple Tuple tuple; // there may be the first tuple that is "cached" by the advancePivot() // if so, use it instead of fetching the tuple from the source block if (firstTuple != null) { tuple = firstTuple; firstTuple = null; } else { tuple = block.next(); } // if the source block is depleted, make a note of it. This is needed in the // advancePivot() if (tuple == null) { finished = true; return null; } remaining--; return tuple; } @Override public void rewind() throws IOException { block.rewind(); } public boolean advancePivot() throws IOException, InterruptedException { // if the source block is empty, there is no more advancing if (finished) { return false; } // fetch the "cache" the next tuple firstTuple = block.next(); // if there is nothing, then we are done if (firstTuple == null) { return false; } // reset the internal state remaining = rowCount; return true; } }