From 9a5ec83baf2cae62268982ebb5230fb91ff2ef33 Mon Sep 17 00:00:00 2001 From: Keith Turner Date: Mon, 15 Jul 2019 11:02:27 -0400 Subject: [PATCH] Make bulk load mapping matching more strict #1260 (#1269) --- .../master/tableOps/bulkVer2/LoadFiles.java | 59 ++++++++++++++----- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/server/master/src/main/java/org/apache/accumulo/master/tableOps/bulkVer2/LoadFiles.java b/server/master/src/main/java/org/apache/accumulo/master/tableOps/bulkVer2/LoadFiles.java index e82478263d1..98d59edc2c8 100644 --- a/server/master/src/main/java/org/apache/accumulo/master/tableOps/bulkVer2/LoadFiles.java +++ b/server/master/src/main/java/org/apache/accumulo/master/tableOps/bulkVer2/LoadFiles.java @@ -19,11 +19,12 @@ import static java.nio.charset.StandardCharsets.UTF_8; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Objects; +import java.util.NoSuchElementException; import java.util.Set; import org.apache.accumulo.core.client.BatchWriter; @@ -340,27 +341,53 @@ private long loadFiles(TableId tableId, Path bulkDir, LoadMappingIterator loadMa return sleepTime; } + private static final Comparator PREV_COMP = Comparator.nullsFirst(Text::compareTo); + private static final Comparator END_COMP = Comparator.nullsLast(Text::compareTo); + /** * Find all the tablets within the provided bulk load mapping range. */ private List findOverlappingTablets(KeyExtent loadRange, Iterator tabletIter) { - List tablets = new ArrayList<>(); - TabletMetadata currentTablet = tabletIter.next(); - // skip tablets until we find the prevEndRow of loadRange - while (!Objects.equals(currentTablet.getPrevEndRow(), loadRange.getPrevEndRow())) { - currentTablet = tabletIter.next(); - } - // we have found the first tablet in the range, add it to the list - tablets.add(currentTablet); - - // find the remaining tablets within the loadRange by - // adding tablets to the list until the endRow matches the loadRange - while (!Objects.equals(currentTablet.getEndRow(), loadRange.getEndRow())) { - currentTablet = tabletIter.next(); - tablets.add(currentTablet); + TabletMetadata currTablet = null; + + try { + + List tablets = new ArrayList<>(); + currTablet = tabletIter.next(); + + int cmp; + + // skip tablets until we find the prevEndRow of loadRange + while ((cmp = PREV_COMP.compare(currTablet.getPrevEndRow(), loadRange.getPrevEndRow())) < 0) { + currTablet = tabletIter.next(); + } + + if (cmp != 0) { + throw new IllegalStateException("Unexpected prev end row " + currTablet + " " + loadRange); + } + + // we have found the first tablet in the range, add it to the list + tablets.add(currTablet); + + // find the remaining tablets within the loadRange by + // adding tablets to the list until the endRow matches the loadRange + while ((cmp = END_COMP.compare(currTablet.getEndRow(), loadRange.getEndRow())) < 0) { + currTablet = tabletIter.next(); + tablets.add(currTablet); + } + + if (cmp != 0) { + throw new IllegalStateException("Unexpected end row " + currTablet + " " + loadRange); + } + + return tablets; + } catch (NoSuchElementException e) { + NoSuchElementException ne2 = new NoSuchElementException( + "Failed to find overlapping tablets " + currTablet + " " + loadRange); + ne2.initCause(e); + throw ne2; } - return tablets; } }