@SuppressWarnings("deprecation") @Override public void commitRow(byte[] row, long startId, long commitId, boolean isDelete, Integer lockId) throws IOException { Get get = new Get(row); get.setMaxVersions(); get.addFamily(DominoConst.INNER_FAMILY); Result r = region.get(get, lockId); if (!containsStatus(r, startId)) { // Other transaction may have committed this row of this version LOG.info( "Commit: No status found, returning: {}.{}", new String(this.getName()), new String(row)); return; } List<KeyValue> versions = r.getColumn(DominoConst.INNER_FAMILY, DominoConst.VERSION_COL); Put commit = new Put(row); commit.setWriteToWAL(true); boolean isFresh = true; if (versions.size() >= DominoConst.MAX_VERSION) { // We need to clean the earliest version. LOG.info( "Commit: rolling version window: {}.{}", new String(this.getName()), new String(row)); isFresh = addClearColumns(commit, versions, r, row, isDelete, commitId, startId, lockId); } KeyValue clearStatusKV = new KeyValue( row, DominoConst.INNER_FAMILY, DominoConst.STATUS_COL, startId, KeyValue.Type.Delete); commit.add(clearStatusKV); byte[] value = DominoConst.versionValue(startId, isDelete); if (isFresh) { KeyValue commitKV = new KeyValue(row, DominoConst.INNER_FAMILY, DominoConst.VERSION_COL, commitId, value); commit.add(commitKV); } // commitNumericModifications(row, startId, lockId, commit); mutateRow(commit, lockId); }
/** * Clear the data out of version window & write them to the second lowest version. * * @param commit * @param versions * @param r * @param row * @param isDelete * @param commitId * @param startId * @param lockId * @return * @throws IOException */ @SuppressWarnings("deprecation") private boolean addClearColumns( Put commit, List<KeyValue> versions, Result r, byte[] row, boolean isDelete, long commitId, long startId, Integer lockId) throws IOException { KeyValue commitKV = new KeyValue( row, DominoConst.INNER_FAMILY, DominoConst.VERSION_COL, commitId, DominoConst.versionValue(startId, isDelete)); NavigableSet<KeyValue> orderedVersions = new TreeSet<KeyValue>(MVCC.VERSION_KV_COMPARATOR); orderedVersions.add(versions.get(versions.size() - 1)); if (versions.size() >= 2) { orderedVersions.add(versions.get(versions.size() - 2)); } orderedVersions.add(commitKV); Iterator<KeyValue> it = orderedVersions.descendingIterator(); KeyValue remove = it.next(); KeyValue prev = it.next(); byte[] removeValue = remove.getValue(); byte[] prevValue = prev.getValue(); long removeCommitId = remove.getTimestamp(); long removeStartId = DominoConst.getVersion(removeValue); long prevStartId = DominoConst.getVersion(prevValue); boolean isFresh = (removeCommitId != commitId); Columns removeCols = new Columns(DominoConst.getColumnsAt(r, removeStartId)); if (!DominoConst.isDeleteVersion(removeValue) && !DominoConst.isDeleteVersion(prevValue)) { Columns prevCols = new Columns(DominoConst.getColumnsAt(r, prevStartId)); Get get = new Get(row); get.setTimeStamp(removeStartId); Result res = region.get(get, lockId); for (Column col : removeCols.cols) { if (prevCols.contains(col.family, col.qualifier)) { continue; // a newer value } // merge it byte[] value = res.getValue(col.family, col.qualifier); prevCols.add(col.family, col.qualifier); commit.add(col.family, col.qualifier, prevStartId, value); } commit.add( DominoConst.INNER_FAMILY, DominoConst.COLUMNS_COL, prevStartId, prevCols.toByteArray()); } if (isFresh) { commit.add( new KeyValue( row, DominoConst.INNER_FAMILY, DominoConst.VERSION_COL, removeCommitId, KeyValue.Type.Delete)); } commit.add( new KeyValue( row, DominoConst.INNER_FAMILY, DominoConst.COLUMNS_COL, removeStartId, KeyValue.Type.Delete)); for (Column col : removeCols.cols) { commit.add(new KeyValue(row, col.family, col.qualifier, removeStartId, KeyValue.Type.Delete)); } return isFresh; }