@Override public Map<Bytes, Map<Column, Bytes>> get(Collection<Bytes> rows, Set<Column> columns) { checkIfOpen(); if (rows.size() == 0 || columns.size() == 0) { return Collections.emptyMap(); } env.getSharedResources().getVisCache().validate(columns); ParallelSnapshotScanner pss = new ParallelSnapshotScanner(rows, columns, env, startTs, stats); Map<Bytes, Map<Column, Bytes>> ret = pss.scan(); for (Entry<Bytes, Map<Column, Bytes>> entry : ret.entrySet()) { updateColumnsRead(entry.getKey(), entry.getValue().keySet()); } return ret; }
Map<Bytes, Map<Column, Bytes>> scan() { long waitTime = SnapshotScanner.INITIAL_WAIT_TIME; long startTime = System.currentTimeMillis(); Map<Bytes, Map<Column, Bytes>> ret = new HashMap<>(); while (true) { List<Entry<Key, Value>> locks = new ArrayList<>(); scan(ret, locks); if (locks.size() > 0) { boolean resolvedAll = LockResolver.resolveLocks(env, startTs, stats, locks, startTime); if (!resolvedAll) { UtilWaitThread.sleep(waitTime); stats.incrementLockWaitTime(waitTime); waitTime = Math.min(SnapshotScanner.MAX_WAIT_TIME, waitTime * 2); } // TODO, could only rescan the row/cols that were locked instead of just the entire row // retain the rows that were locked for future scans HashSet<Bytes> lockedRows = new HashSet<>(); for (Entry<Key, Value> entry : locks) { lockedRows.add(ByteUtil.toBytes(entry.getKey().getRowData())); } unscannedRows.retainAll(lockedRows); continue; } for (Map<Column, Bytes> cols : ret.values()) { stats.incrementEntriesReturned(cols.size()); } return ret; } }
void scan(Map<Bytes, Map<Column, Bytes>> ret, List<Entry<Key, Value>> locks) { BatchScanner bs = setupBatchScanner(unscannedRows, columns); try { for (Entry<Key, Value> entry : bs) { Bytes row = ByteUtil.toBytes(entry.getKey().getRowData()); Bytes cf = ByteUtil.toBytes(entry.getKey().getColumnFamilyData()); Bytes cq = ByteUtil.toBytes(entry.getKey().getColumnQualifierData()); Column col = new Column(cf, cq, ByteUtil.toBytes(entry.getKey().getColumnVisibilityData())); long colType = entry.getKey().getTimestamp() & ColumnConstants.PREFIX_MASK; if (colType == ColumnConstants.LOCK_PREFIX) { locks.add(entry); } else if (colType == ColumnConstants.DATA_PREFIX) { Map<Column, Bytes> cols = ret.get(row); if (cols == null) { cols = new HashMap<>(); ret.put(row, cols); } cols.put(col, Bytes.of(entry.getValue().get())); } else { throw new IllegalArgumentException("Unexpected column type " + colType); } } } finally { bs.close(); } }