[ https://issues.apache.org/jira/browse/ACCUMULO-4502?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15602717#comment-15602717 ]
Ivan Bella edited comment on ACCUMULO-4502 at 10/24/16 6:57 PM: ---------------------------------------------------------------- The condition in the HeapIterator is that the {{topIdx == null}} which implies that hasTop should have returned false. In PartialMutationSkippingIterator.consume it is simply doing the following: {code} protected void consume() throws IOException while (getSource().hasTop() && ((MemKey) getSource().getTopKey()).kvCount > kvCount) getSource().next(); } {code} So obviously it is calling hasTop() before calling next(). The rub is that there is a SourceSwitchingIterator in between the PartialMutationSkippingIterator and the HeapIterator at the bottom. Most likely a minor compaction caused the SourceSwitchingIterator to switch via the switchNow method. When that happens the following code in {{_switchNow()}} is invoked: {code} if (switchSource()) { if (key != null) { iter.seek(...) } } {code} So if {{getSource().getTop()}} was invoked in the PartialMutationSkippingIterator, then switchSource is called but BEFORE the nested {{if (key != null) iter.seek(...)}} is invoked, the {{getSource().next()}} is invoked by the PartialMutationSkippingIterator: this scenario would leave the topIdx to be null in the HeapIterator (most likely the RFile.Reader at this point) and subsequently cause this exception. (elserj: some wiki formatting for readability) was (Author: ivan.bella): The condition in the HeapIterator is that the {{topIdx == null}} which implies that hasTop should have returned false. In PartialMutationSkippingIterator.consume it is simply doing the following: {code} protected void consume() throws IOException while (getSource().hasTop() && ((MemKey) getSource().getTopKey()).kvCount > kvCount) getSource().next(); } {code} So obviously it is calling hasTop() before calling next(). The rub is that there is a SourceSwitchingIterator in between the PartialMutationSkippingIterator and the HeapIterator at the bottom. Most likely a minor compaction caused the SourceSwitchingIterator to switch via the switchNow method. When that happens the following code in {{_switchNow()}} is invoked: {code} if (switchSource()) { if (key != null) { iter.seek(...) } } {code} So if {{getSource().getTop()}} was invoked in the PartialMutationSkippingIterator, then switchSource is called but BEFORE the nested {{ if (key != null) \{ iter.seek(...) \} }} is invoked, the {{getSource().next()}} is invoked by the PartialMutationSkippingIterator: this scenario would leave the topIdx to be null in the HeapIterator (most likely the RFile.Reader at this point) and subsequently cause this exception. (elserj: some wiki formatting for readability) > Called next when there is no top > -------------------------------- > > Key: ACCUMULO-4502 > URL: https://issues.apache.org/jira/browse/ACCUMULO-4502 > Project: Accumulo > Issue Type: Bug > Components: core, tserver > Affects Versions: 1.6.6 > Reporter: Ivan Bella > > This happens very rarely but we have seen the following exception (pulled > from a server running 1.6.4). Looking at the code I believe this condition > can still happen in 1.8.0: > java.util.concurrent.ExecutionException: java.lang.IllegalStateException: > Called next() when there is no top > ... > Caused by: java.lang.IllegalStateException: Called next() when there is no top > HeapIterator.next(HeapIterator.java: 77) > WrappingIterator.next(WrappingIterator.java: 96) > MemKeyConversionIterator.next(InMemoryMap.java:162) > SourceSwitchingIterator.readNext(SourceSwitchingIterator.java: 139) > SourceSwitchingIterator.next(SourceSwitchingIterator.java: 123) > PartialMutationSkippingIterator.consume(InMemoryMap.java:108) > SkippingIterator.seek(SkippingIterator.java:43) -- This message was sent by Atlassian JIRA (v6.3.4#6332)