// Copyright 2017 JanusGraph Authors // // 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.janusgraph.hadoop.formats.hbase; import com.google.common.base.Preconditions; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; import org.janusgraph.diskstorage.Entry; import org.janusgraph.diskstorage.StaticBuffer; import org.janusgraph.diskstorage.util.StaticArrayBuffer; import org.janusgraph.diskstorage.util.StaticArrayEntry; import org.apache.hadoop.mapreduce.InputSplit; import org.apache.hadoop.mapreduce.RecordReader; import org.apache.hadoop.mapreduce.TaskAttemptContext; import java.io.IOException; import java.util.Iterator; import java.util.Map; import java.util.NavigableMap; public class HBaseBinaryRecordReader extends RecordReader<StaticBuffer, Iterable<Entry>> { private RecordReader<ImmutableBytesWritable, Result> reader; private final byte[] edgestoreFamilyBytes; public HBaseBinaryRecordReader(final RecordReader<ImmutableBytesWritable, Result> reader, final byte[] edgestoreFamilyBytes) { this.reader = reader; this.edgestoreFamilyBytes = edgestoreFamilyBytes; } @Override public void initialize(final InputSplit inputSplit, final TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException { reader.initialize(inputSplit, taskAttemptContext); } @Override public boolean nextKeyValue() throws IOException, InterruptedException { return reader.nextKeyValue(); } @Override public StaticBuffer getCurrentKey() throws IOException, InterruptedException { return StaticArrayBuffer.of(reader.getCurrentKey().copyBytes()); } @Override public Iterable<Entry> getCurrentValue() throws IOException, InterruptedException { return new HBaseMapIterable(reader.getCurrentValue().getMap().get(edgestoreFamilyBytes)); } @Override public void close() throws IOException { this.reader.close(); } @Override public float getProgress() throws IOException, InterruptedException { return this.reader.getProgress(); } private static class HBaseMapIterable implements Iterable<Entry> { private final NavigableMap<byte[], NavigableMap<Long, byte[]>> columnValues; public HBaseMapIterable(final NavigableMap<byte[], NavigableMap<Long, byte[]>> columnValues) { Preconditions.checkNotNull(columnValues); this.columnValues = columnValues; } @Override public Iterator<Entry> iterator() { return new HBaseMapIterator(columnValues.entrySet().iterator()); } } private static class HBaseMapIterator implements Iterator<Entry> { private final Iterator<Map.Entry<byte[], NavigableMap<Long, byte[]>>> iterator; public HBaseMapIterator(final Iterator<Map.Entry<byte[], NavigableMap<Long, byte[]>>> iterator) { this.iterator = iterator; } @Override public boolean hasNext() { return iterator.hasNext(); } @Override public Entry next() { final Map.Entry<byte[], NavigableMap<Long, byte[]>> entry = iterator.next(); byte[] col = entry.getKey(); byte[] val = entry.getValue().lastEntry().getValue(); return StaticArrayEntry.of(new StaticArrayBuffer(col), new StaticArrayBuffer(val)); } @Override public void remove() { throw new UnsupportedOperationException(); } } }