public List<Record> readVersions( RecordId recordId, Long fromVersion, Long toVersion, QName... fieldNames) throws RepositoryException, InterruptedException { ArgumentValidator.notNull(recordId, "recordId"); ArgumentValidator.notNull(fromVersion, "fromVersion"); ArgumentValidator.notNull(toVersion, "toVersion"); if (fromVersion > toVersion) { throw new IllegalArgumentException( "fromVersion '" + fromVersion + "' must be smaller or equal to toVersion '" + toVersion + "'"); } FieldTypes fieldTypes = typeManager.getFieldTypesSnapshot(); List<FieldType> fields = getFieldTypesFromNames(fieldTypes, fieldNames); int numberOfVersionsToRetrieve = (int) (toVersion - fromVersion + 1); Result result = getRow(recordId, toVersion, numberOfVersionsToRetrieve, fields); if (fromVersion < 1L) fromVersion = 1L; // Put the fromVersion to a sensible value Long latestVersion = recdec.getLatestVersion(result); if (latestVersion < toVersion) toVersion = latestVersion; // Limit the toVersion to the highest possible version List<Long> versionsToRead = new ArrayList<Long>(); for (long version = fromVersion; version <= toVersion; version++) { versionsToRead.add(version); } return recdec.decodeRecords(recordId, versionsToRead, result, fieldTypes); }
public List<Record> readVersions(RecordId recordId, List<Long> versions, QName... fieldNames) throws RepositoryException, InterruptedException { ArgumentValidator.notNull(recordId, "recordId"); ArgumentValidator.notNull(versions, "versions"); if (versions.isEmpty()) return new ArrayList<Record>(); Collections.sort(versions); FieldTypes fieldTypes = typeManager.getFieldTypesSnapshot(); List<FieldType> fields = getFieldTypesFromNames(fieldTypes, fieldNames); Long lowestRequestedVersion = versions.get(0); Long highestRequestedVersion = versions.get(versions.size() - 1); int numberOfVersionsToRetrieve = (int) (highestRequestedVersion - lowestRequestedVersion + 1); Result result = getRow(recordId, highestRequestedVersion, numberOfVersionsToRetrieve, fields); Long latestVersion = recdec.getLatestVersion(result); // Drop the versions that are higher than the latestVersion List<Long> validVersions = new ArrayList<Long>(); for (Long version : versions) { if (version > latestVersion) break; validVersions.add(version); } return recdec.decodeRecords(recordId, validVersions, result, fieldTypes); }
// Retrieves the row from the table and check if it exists and has not been flagged as deleted protected Map<RecordId, Result> getRows(List<RecordId> recordIds, List<FieldType> fields) throws RecordException { Map<RecordId, Result> results = new HashMap<RecordId, Result>(); try { List<Get> gets = new ArrayList<Get>(); for (RecordId recordId : recordIds) { Get get = new Get(recordId.toBytes()); // Add the columns for the fields to get addFieldsToGet(get, fields); get.setMaxVersions(1); // Only retrieve the most recent version of each field gets.add(get); } // Retrieve the data from the repository int i = 0; for (Result result : recordTable.get(gets)) { if (result == null || result.isEmpty()) { i++; // Skip this recordId (instead of throwing a RecordNotFoundException) continue; } // Check if the record was deleted byte[] deleted = recdec.getLatest(result, RecordCf.DATA.bytes, RecordColumn.DELETED.bytes); if ((deleted == null) || (Bytes.toBoolean(deleted))) { i++; // Skip this recordId (instead of throwing a RecordNotFoundException) continue; } results.put(recordIds.get(i++), result); } } catch (IOException e) { throw new RecordException( "Exception occurred while retrieving records '" + recordIds + "' from HBase table", e); } return results; }
private void addFieldsToGet(Get get, List<FieldType> fields) { if (fields != null && (!fields.isEmpty())) { for (FieldType field : fields) { get.addColumn(RecordCf.DATA.bytes, ((FieldTypeImpl) field).getQualifier()); } RecordDecoder.addSystemColumnsToGet(get); } else { // Retrieve everything get.addFamily(RecordCf.DATA.bytes); } }
private List<Record> read(List<RecordId> recordIds, List<FieldType> fields, FieldTypes fieldTypes) throws RepositoryException, InterruptedException { long before = System.currentTimeMillis(); try { ArgumentValidator.notNull(recordIds, "recordIds"); List<Record> records = new ArrayList<Record>(); if (recordIds.isEmpty()) return records; Map<RecordId, Result> results = getRows(recordIds, fields); for (Entry<RecordId, Result> entry : results.entrySet()) { Long version = recdec.getLatestVersion(entry.getValue()); records.add( recdec.decodeRecord(entry.getKey(), version, null, entry.getValue(), fieldTypes)); } return records; } finally { if (metrics != null) metrics.report(Action.READ, System.currentTimeMillis() - before); } }
protected Record read( RecordId recordId, Long requestedVersion, List<FieldType> fields, FieldTypes fieldTypes) throws RepositoryException, InterruptedException { long before = System.currentTimeMillis(); try { ArgumentValidator.notNull(recordId, "recordId"); Result result = getRow(recordId, requestedVersion, 1, fields); Long latestVersion = recdec.getLatestVersion(result); if (requestedVersion == null) { // Latest version can still be null if there are only non-versioned fields in the record requestedVersion = latestVersion; } else { if (latestVersion == null || latestVersion < requestedVersion) { // The requested version is higher than the highest existing version throw new VersionNotFoundException(recordId, requestedVersion); } } return recdec.decodeRecord(recordId, requestedVersion, null, result, fieldTypes); } finally { if (metrics != null) metrics.report(Action.READ, System.currentTimeMillis() - before); } }
private ResultScanner createHBaseResultScanner(RecordScan scan) throws RepositoryException, InterruptedException { Scan hbaseScan = new Scan(); hbaseScan.setMaxVersions(1); if (scan.getRawStartRecordId() != null) { hbaseScan.setStartRow(scan.getRawStartRecordId()); } else if (scan.getStartRecordId() != null) { hbaseScan.setStartRow(scan.getStartRecordId().toBytes()); } if (scan.getRawStopRecordId() != null) { hbaseScan.setStopRow(scan.getRawStopRecordId()); } else if (scan.getStopRecordId() != null) { hbaseScan.setStopRow(scan.getStopRecordId().toBytes()); } // Filters FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL); // filter out deleted records filterList.addFilter(REAL_RECORDS_FILTER); // add user's filter if (scan.getRecordFilter() != null) { Filter filter = filterFactory.createHBaseFilter(scan.getRecordFilter(), this, filterFactory); filterList.addFilter(filter); } hbaseScan.setFilter(filterList); hbaseScan.setCaching(scan.getCaching()); hbaseScan.setCacheBlocks(scan.getCacheBlocks()); ReturnFields returnFields = scan.getReturnFields(); if (returnFields != null && returnFields.getType() != ReturnFields.Type.ALL) { RecordDecoder.addSystemColumnsToScan(hbaseScan); switch (returnFields.getType()) { case ENUM: for (QName field : returnFields.getFields()) { FieldTypeImpl fieldType = (FieldTypeImpl) typeManager.getFieldTypeByName(field); hbaseScan.addColumn(RecordCf.DATA.bytes, fieldType.getQualifier()); } break; case NONE: // nothing to add break; default: throw new RuntimeException("Unrecognized ReturnFields type: " + returnFields.getType()); } } else { hbaseScan.addFamily(RecordCf.DATA.bytes); } ResultScanner hbaseScanner; try { hbaseScanner = recordTable.getScanner(hbaseScan); } catch (IOException e) { throw new RecordException("Error creating scanner", e); } return hbaseScanner; }
@Override public Record newRecord(RecordId recordId) { ArgumentValidator.notNull(recordId, "recordId"); return recdec.newRecord(recordId); }
@Override public Record newRecord() { return recdec.newRecord(); }