-
Notifications
You must be signed in to change notification settings - Fork 3.4k
HBASE-21596 Delete for a specific cell version can bring back version… #2009
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3151,6 +3151,7 @@ public void prepareDeleteTimestamps(Mutation mutation, Map<byte[], List<Cell>> f | |
| List<Cell> cells = e.getValue(); | ||
| assert cells instanceof RandomAccess; | ||
|
|
||
| List<Cell> deleteCells = new ArrayList<>(); | ||
| Map<byte[], Integer> kvCount = new TreeMap<>(Bytes.BYTES_COMPARATOR); | ||
| int listSize = cells.size(); | ||
| for (int i=0; i < listSize; i++) { | ||
|
|
@@ -3170,37 +3171,87 @@ public void prepareDeleteTimestamps(Mutation mutation, Map<byte[], List<Cell>> f | |
| count = kvCount.get(qual); | ||
|
|
||
| Get get = new Get(CellUtil.cloneRow(cell)); | ||
| get.readVersions(count); | ||
| get.addColumn(family, qual); | ||
| get.readVersions(Integer.MAX_VALUE); | ||
| if (coprocessorHost != null) { | ||
| if (!coprocessorHost.prePrepareTimeStampForDeleteVersion(mutation, cell, | ||
| byteNow, get)) { | ||
| updateDeleteLatestVersionTimestamp(cell, get, count, byteNow); | ||
| updateDeleteLatestVersionTimestamp(cell, get, count, | ||
| this.htableDescriptor.getColumnFamily(family).getMaxVersions(), | ||
| byteNow, deleteCells); | ||
|
|
||
| } | ||
| } else { | ||
| updateDeleteLatestVersionTimestamp(cell, get, count, byteNow); | ||
| updateDeleteLatestVersionTimestamp(cell, get, count, | ||
| this.htableDescriptor.getColumnFamily(family).getMaxVersions(), | ||
| byteNow, deleteCells); | ||
| } | ||
| } else { | ||
| PrivateCellUtil.updateLatestStamp(cell, byteNow); | ||
| deleteCells.add(cell); | ||
| } | ||
| } | ||
| e.setValue(deleteCells); | ||
| } | ||
| } | ||
|
|
||
| void updateDeleteLatestVersionTimestamp(Cell cell, Get get, int count, byte[] byteNow) | ||
| throws IOException { | ||
| List<Cell> result = get(get, false); | ||
|
|
||
| private void updateDeleteLatestVersionTimestamp(Cell cell, Get get, int count, int maxVersions, | ||
| byte[] byteNow, List<Cell> deleteCells) throws IOException { | ||
| List<Cell> result = new ArrayList<>(deleteCells); | ||
| Scan scan = new Scan(get); | ||
| scan.setRaw(true); | ||
| this.getScanner(scan).next(result); | ||
| List<Cell> cells = new ArrayList<>(); | ||
| if (result.size() < count) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. result sorting doesn't seem useful for this condition. Can we avoid sorting for this?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. |
||
| // Nothing to delete | ||
| PrivateCellUtil.updateLatestStamp(cell, byteNow); | ||
| return; | ||
| } | ||
| if (result.size() > count) { | ||
| throw new RuntimeException("Unexpected size: " + result.size()); | ||
| cells.add(cell); | ||
| deleteCells.addAll(cells); | ||
| } else if (result.size() > count) { | ||
| int currentVersion = 0; | ||
| long latestCellTS = Long.MAX_VALUE; | ||
| result.sort((cell1, cell2) -> { | ||
| if(cell1.getTimestamp()>cell2.getTimestamp()){ | ||
| return -1; | ||
| } else if(cell1.getTimestamp()<cell2.getTimestamp()){ | ||
| return 1; | ||
| } else { | ||
| if(CellUtil.isDelete(cell1)){ | ||
| return -1; | ||
| } else if (CellUtil.isDelete(cell2)){ | ||
| return 1; | ||
| } | ||
| } | ||
| return 0; | ||
| }); | ||
| for(Cell getCell : result){ | ||
| if(!(CellUtil.matchingFamily(getCell, cell) && CellUtil.matchingQualifier(getCell, cell))){ | ||
| continue; | ||
| } | ||
| if(!PrivateCellUtil.isDeleteType(getCell) && getCell.getTimestamp()!=latestCellTS){ | ||
| if (currentVersion >= maxVersions) { | ||
| Cell tempCell = null; | ||
| try { | ||
| tempCell = PrivateCellUtil.deepClone(cell); | ||
| } catch (CloneNotSupportedException e) { | ||
| throw new IOException(e); | ||
| } | ||
| PrivateCellUtil.setTimestamp(tempCell, getCell.getTimestamp()); | ||
| cells.add(tempCell); | ||
| } else if (currentVersion == 0) { | ||
| PrivateCellUtil.setTimestamp(cell, getCell.getTimestamp()); | ||
| cells.add(cell); | ||
| } | ||
| currentVersion++; | ||
| } | ||
| latestCellTS = getCell.getTimestamp(); | ||
| } | ||
|
|
||
| } else { | ||
| Cell getCell = result.get(0); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure if sorting of result is required here. If not required, rest looks good.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not needed, because we don't have to worry about additional versions, we only need to put a single marker for current TS. |
||
| PrivateCellUtil.setTimestamp(cell, getCell.getTimestamp()); | ||
| cells.add(cell); | ||
virajjasani marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| Cell getCell = result.get(count - 1); | ||
| PrivateCellUtil.setTimestamp(cell, getCell.getTimestamp()); | ||
| deleteCells.addAll(cells); | ||
| } | ||
|
|
||
| @Override | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you prefer using a boolean to make single call to updateDeleteLatestVersionTimestamp?
Only if you feel this is more readable :)