Search in sources :

Example 1 with YieldCallback

use of org.apache.accumulo.core.iterators.YieldCallback in project accumulo by apache.

the class YieldingTestCase method test.

@Override
public IteratorTestOutput test(IteratorTestInput testInput) {
    final SortedKeyValueIterator<Key, Value> skvi = IteratorTestUtil.instantiateIterator(testInput);
    final SortedKeyValueIterator<Key, Value> source = IteratorTestUtil.createSource(testInput);
    try {
        skvi.init(source, testInput.getIteratorOptions(), new SimpleIteratorEnvironment());
        YieldCallback<Key> yield = new YieldCallback<>();
        skvi.enableYielding(yield);
        skvi.seek(testInput.getRange(), testInput.getFamilies(), testInput.isInclusive());
        return new IteratorTestOutput(consume(testInput, skvi, yield));
    } catch (IOException e) {
        return new IteratorTestOutput(e);
    }
}
Also used : YieldCallback(org.apache.accumulo.core.iterators.YieldCallback) IteratorTestOutput(org.apache.accumulo.iteratortest.IteratorTestOutput) SimpleIteratorEnvironment(org.apache.accumulo.iteratortest.environments.SimpleIteratorEnvironment) Value(org.apache.accumulo.core.data.Value) IOException(java.io.IOException) Key(org.apache.accumulo.core.data.Key)

Example 2 with YieldCallback

use of org.apache.accumulo.core.iterators.YieldCallback in project accumulo by apache.

the class Tablet method nextBatch.

Batch nextBatch(SortedKeyValueIterator<Key, Value> iter, Range range, int num, Set<Column> columns, long batchTimeOut, boolean isolated) throws IOException {
    // log.info("In nextBatch..");
    long stopTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(batchTimeOut);
    if (batchTimeOut == Long.MAX_VALUE || batchTimeOut <= 0) {
        batchTimeOut = 0;
    }
    List<KVEntry> results = new ArrayList<>();
    Key key = null;
    Value value;
    long resultSize = 0L;
    long resultBytes = 0L;
    long maxResultsSize = tableConfiguration.getAsBytes(Property.TABLE_SCAN_MAXMEM);
    Key continueKey = null;
    boolean skipContinueKey = false;
    YieldCallback<Key> yield = new YieldCallback<>();
    // we cannot yield if we are in isolation mode
    if (!isolated) {
        iter.enableYielding(yield);
    }
    if (columns.size() == 0) {
        iter.seek(range, LocalityGroupUtil.EMPTY_CF_SET, false);
    } else {
        iter.seek(range, LocalityGroupUtil.families(columns), true);
    }
    while (iter.hasTop()) {
        if (yield.hasYielded()) {
            throw new IOException("Coding error: hasTop returned true but has yielded at " + yield.getPositionAndReset());
        }
        value = iter.getTopValue();
        key = iter.getTopKey();
        // copies key and value
        KVEntry kvEntry = new KVEntry(key, value);
        results.add(kvEntry);
        resultSize += kvEntry.estimateMemoryUsed();
        resultBytes += kvEntry.numBytes();
        boolean timesUp = batchTimeOut > 0 && System.nanoTime() >= stopTime;
        if (resultSize >= maxResultsSize || results.size() >= num || timesUp) {
            continueKey = new Key(key);
            skipContinueKey = true;
            break;
        }
        iter.next();
    }
    if (yield.hasYielded()) {
        continueKey = new Key(yield.getPositionAndReset());
        skipContinueKey = true;
        if (!range.contains(continueKey)) {
            throw new IOException("Underlying iterator yielded to a position outside of its range: " + continueKey + " not in " + range);
        }
        if (!results.isEmpty() && continueKey.compareTo(results.get(results.size() - 1).getKey()) <= 0) {
            throw new IOException("Underlying iterator yielded to a position that does not follow the last key returned: " + continueKey + " <= " + results.get(results.size() - 1).getKey());
        }
        log.debug("Scan yield detected at position " + continueKey);
        Metrics scanMetrics = getTabletServer().getScanMetrics();
        if (scanMetrics.isEnabled())
            scanMetrics.add(TabletServerScanMetrics.YIELD, 1);
    } else if (!iter.hasTop()) {
        // end of tablet has been reached
        continueKey = null;
        if (results.size() == 0)
            results = null;
    }
    return new Batch(skipContinueKey, results, continueKey, resultBytes);
}
Also used : YieldCallback(org.apache.accumulo.core.iterators.YieldCallback) Metrics(org.apache.accumulo.server.metrics.Metrics) TabletServerScanMetrics(org.apache.accumulo.tserver.metrics.TabletServerScanMetrics) TabletServerMinCMetrics(org.apache.accumulo.tserver.metrics.TabletServerMinCMetrics) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) Value(org.apache.accumulo.core.data.Value) DataFileValue(org.apache.accumulo.core.metadata.schema.DataFileValue) IOException(java.io.IOException) Key(org.apache.accumulo.core.data.Key)

Example 3 with YieldCallback

use of org.apache.accumulo.core.iterators.YieldCallback in project accumulo by apache.

the class Tablet method lookup.

private LookupResult lookup(SortedKeyValueIterator<Key, Value> mmfi, List<Range> ranges, HashSet<Column> columnSet, List<KVEntry> results, long maxResultsSize, long batchTimeOut) throws IOException {
    LookupResult lookupResult = new LookupResult();
    boolean exceededMemoryUsage = false;
    boolean tabletClosed = false;
    Set<ByteSequence> cfset = null;
    if (columnSet.size() > 0)
        cfset = LocalityGroupUtil.families(columnSet);
    long returnTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(batchTimeOut);
    if (batchTimeOut <= 0 || batchTimeOut == Long.MAX_VALUE) {
        batchTimeOut = 0;
    }
    // determine if the iterator supported yielding
    YieldCallback<Key> yield = new YieldCallback<>();
    mmfi.enableYielding(yield);
    boolean yielded = false;
    for (Range range : ranges) {
        boolean timesUp = batchTimeOut > 0 && System.nanoTime() > returnTime;
        if (exceededMemoryUsage || tabletClosed || timesUp || yielded) {
            lookupResult.unfinishedRanges.add(range);
            continue;
        }
        int entriesAdded = 0;
        try {
            if (cfset != null)
                mmfi.seek(range, cfset, true);
            else
                mmfi.seek(range, LocalityGroupUtil.EMPTY_CF_SET, false);
            while (mmfi.hasTop()) {
                if (yield.hasYielded()) {
                    throw new IOException("Coding error: hasTop returned true but has yielded at " + yield.getPositionAndReset());
                }
                Key key = mmfi.getTopKey();
                KVEntry kve = new KVEntry(key, mmfi.getTopValue());
                results.add(kve);
                entriesAdded++;
                lookupResult.bytesAdded += kve.estimateMemoryUsed();
                lookupResult.dataSize += kve.numBytes();
                exceededMemoryUsage = lookupResult.bytesAdded > maxResultsSize;
                timesUp = batchTimeOut > 0 && System.nanoTime() > returnTime;
                if (exceededMemoryUsage || timesUp) {
                    addUnfinishedRange(lookupResult, range, key, false);
                    break;
                }
                mmfi.next();
            }
            if (yield.hasYielded()) {
                yielded = true;
                Key yieldPosition = yield.getPositionAndReset();
                if (!range.contains(yieldPosition)) {
                    throw new IOException("Underlying iterator yielded to a position outside of its range: " + yieldPosition + " not in " + range);
                }
                if (!results.isEmpty() && yieldPosition.compareTo(results.get(results.size() - 1).getKey()) <= 0) {
                    throw new IOException("Underlying iterator yielded to a position that does not follow the last key returned: " + yieldPosition + " <= " + results.get(results.size() - 1).getKey());
                }
                addUnfinishedRange(lookupResult, range, yieldPosition, false);
                log.debug("Scan yield detected at position " + yieldPosition);
                Metrics scanMetrics = getTabletServer().getScanMetrics();
                if (scanMetrics.isEnabled())
                    scanMetrics.add(TabletServerScanMetrics.YIELD, 1);
            }
        } catch (TooManyFilesException tmfe) {
            // treat this as a closed tablet, and let the client retry
            log.warn("Tablet {} has too many files, batch lookup can not run", getExtent());
            handleTabletClosedDuringScan(results, lookupResult, exceededMemoryUsage, range, entriesAdded);
            tabletClosed = true;
        } catch (IOException ioe) {
            if (shutdownInProgress()) {
                // assume HDFS shutdown hook caused this exception
                log.debug("IOException while shutdown in progress", ioe);
                handleTabletClosedDuringScan(results, lookupResult, exceededMemoryUsage, range, entriesAdded);
                tabletClosed = true;
            } else {
                throw ioe;
            }
        } catch (IterationInterruptedException iie) {
            if (isClosed()) {
                handleTabletClosedDuringScan(results, lookupResult, exceededMemoryUsage, range, entriesAdded);
                tabletClosed = true;
            } else {
                throw iie;
            }
        } catch (TabletClosedException tce) {
            handleTabletClosedDuringScan(results, lookupResult, exceededMemoryUsage, range, entriesAdded);
            tabletClosed = true;
        }
    }
    return lookupResult;
}
Also used : YieldCallback(org.apache.accumulo.core.iterators.YieldCallback) TooManyFilesException(org.apache.accumulo.tserver.TooManyFilesException) IOException(java.io.IOException) Range(org.apache.accumulo.core.data.Range) Metrics(org.apache.accumulo.server.metrics.Metrics) TabletServerScanMetrics(org.apache.accumulo.tserver.metrics.TabletServerScanMetrics) TabletServerMinCMetrics(org.apache.accumulo.tserver.metrics.TabletServerMinCMetrics) IterationInterruptedException(org.apache.accumulo.core.iterators.IterationInterruptedException) ByteSequence(org.apache.accumulo.core.data.ByteSequence) Key(org.apache.accumulo.core.data.Key)

Example 4 with YieldCallback

use of org.apache.accumulo.core.iterators.YieldCallback in project accumulo by apache.

the class SourceSwitchingIteratorTest method testYield.

public void testYield() throws Exception {
    TreeMap<Key, Value> tm1 = new TreeMap<>();
    put(tm1, "r1", "cf1", "cq1", 5, "v1");
    put(tm1, "r1", "cf1", "cq3", 5, "v2");
    put(tm1, "r2", "cf1", "cq1", 5, "v3");
    SortedMapIterator smi = new SortedMapIterator(tm1);
    YieldingIterator ymi = new YieldingIterator(smi);
    TestDataSource tds = new TestDataSource(ymi);
    SourceSwitchingIterator ssi = new SourceSwitchingIterator(tds);
    YieldCallback<Key> yield = new YieldCallback<>();
    ssi.enableYielding(yield);
    Range r = new Range();
    ssi.seek(r, new ArrayList<>(), false);
    r = yield(r, ssi, yield);
    testAndCallNext(ssi, "r1", "cf1", "cq1", 5, "v1", true);
    r = yield(r, ssi, yield);
    testAndCallNext(ssi, "r1", "cf1", "cq3", 5, "v2", true);
    r = yield(r, ssi, yield);
    testAndCallNext(ssi, "r2", "cf1", "cq1", 5, "v3", true);
    r = yield(r, ssi, yield);
    assertFalse(ssi.hasTop());
}
Also used : YieldCallback(org.apache.accumulo.core.iterators.YieldCallback) Value(org.apache.accumulo.core.data.Value) TreeMap(java.util.TreeMap) SortedMapIterator(org.apache.accumulo.core.iterators.SortedMapIterator) Range(org.apache.accumulo.core.data.Range) Key(org.apache.accumulo.core.data.Key) PartialKey(org.apache.accumulo.core.data.PartialKey)

Aggregations

Key (org.apache.accumulo.core.data.Key)4 YieldCallback (org.apache.accumulo.core.iterators.YieldCallback)4 IOException (java.io.IOException)3 Value (org.apache.accumulo.core.data.Value)3 Range (org.apache.accumulo.core.data.Range)2 Metrics (org.apache.accumulo.server.metrics.Metrics)2 TabletServerMinCMetrics (org.apache.accumulo.tserver.metrics.TabletServerMinCMetrics)2 TabletServerScanMetrics (org.apache.accumulo.tserver.metrics.TabletServerScanMetrics)2 ArrayList (java.util.ArrayList)1 TreeMap (java.util.TreeMap)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 ByteSequence (org.apache.accumulo.core.data.ByteSequence)1 PartialKey (org.apache.accumulo.core.data.PartialKey)1 IterationInterruptedException (org.apache.accumulo.core.iterators.IterationInterruptedException)1 SortedMapIterator (org.apache.accumulo.core.iterators.SortedMapIterator)1 DataFileValue (org.apache.accumulo.core.metadata.schema.DataFileValue)1 IteratorTestOutput (org.apache.accumulo.iteratortest.IteratorTestOutput)1 SimpleIteratorEnvironment (org.apache.accumulo.iteratortest.environments.SimpleIteratorEnvironment)1 TooManyFilesException (org.apache.accumulo.tserver.TooManyFilesException)1