/*
* Copyright 2012 NGDATA nv
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.lilyproject.repository.impl.filter;
import java.util.Set;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.util.Bytes;
import org.lilyproject.repository.api.LRepository;
import org.lilyproject.repository.api.RecordType;
import org.lilyproject.repository.api.RepositoryException;
import org.lilyproject.repository.api.SchemaId;
import org.lilyproject.repository.api.filter.RecordFilter;
import org.lilyproject.repository.api.filter.RecordTypeFilter;
import org.lilyproject.repository.spi.HBaseRecordFilterFactory;
import static org.lilyproject.util.hbase.LilyHBaseSchema.RecordCf;
import static org.lilyproject.util.hbase.LilyHBaseSchema.RecordColumn;
public class HBaseRecordTypeFilter implements HBaseRecordFilterFactory {
@Override
public Filter createHBaseFilter(RecordFilter uncastFilter, LRepository repository, HBaseRecordFilterFactory factory)
throws RepositoryException, InterruptedException {
if (!(uncastFilter instanceof RecordTypeFilter)) {
return null;
}
RecordTypeFilter filter = (RecordTypeFilter)uncastFilter;
Filter result = null;
if (filter.getRecordType() == null) {
throw new IllegalArgumentException("A RecordTypeFilter should at least specify the record type name.");
}
RecordType recordType = repository.getTypeManager().getRecordTypeByName(filter.getRecordType(), null);
RecordTypeFilter.Operator operator =
filter.getOperator() != null ? filter.getOperator() : RecordTypeFilter.Operator.EQUALS;
switch (operator) {
case EQUALS:
Filter nameFilter = createRecordTypeFilter(recordType.getId());
Filter versionFilter = null;
if (filter.getVersion() != null) {
versionFilter = new SingleColumnValueFilter(RecordCf.DATA.bytes,
RecordColumn.NON_VERSIONED_RT_VERSION.bytes, CompareFilter.CompareOp.EQUAL,
Bytes.toBytes(filter.getVersion()));
}
if (versionFilter == null) {
result = nameFilter;
} else {
FilterList list = new FilterList(FilterList.Operator.MUST_PASS_ALL);
list.addFilter(nameFilter);
list.addFilter(versionFilter);
result = list;
}
break;
case INSTANCE_OF:
Set<SchemaId> subtypes = repository.getTypeManager().findSubtypes(recordType.getId());
FilterList list = new FilterList(FilterList.Operator.MUST_PASS_ONE);
list.addFilter(createRecordTypeFilter(recordType.getId()));
for (SchemaId subType : subtypes) {
list.addFilter(createRecordTypeFilter(subType));
}
result = list;
break;
default:
throw new RuntimeException("Unexpected operator: " + filter.getOperator());
}
return result;
}
private Filter createRecordTypeFilter(SchemaId schemaId) {
return new SingleColumnValueFilter(RecordCf.DATA.bytes, RecordColumn.NON_VERSIONED_RT_ID.bytes,
CompareFilter.CompareOp.EQUAL, schemaId.getBytes());
}
}