HBASE-4347 Remove duplicated code from Put, Delete, Get, Scan, MultiPut
git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1167569 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
743d846b9e
commit
699e15b7a1
|
@ -472,6 +472,8 @@ Release 0.91.0 - Unreleased
|
|||
HBASE-4342 Update Thrift to 0.7.0 (Moaz Reyad)
|
||||
HBASE-4260 Expose a command to manually trigger an HLog roll
|
||||
(ramkrishna.s.vasudevan)
|
||||
HBASE-4347 Remove duplicated code from Put, Delete, Get, Scan, MultiPut
|
||||
(Lars Hofhansl)
|
||||
|
||||
TASKS
|
||||
HBASE-3559 Move report of split to master OFF the heartbeat channel
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2011 The Apache Software Foundation
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.hadoop.hbase.client;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface Attributes {
|
||||
/**
|
||||
* Sets an attribute.
|
||||
* In case value = null attribute is removed from the attributes map.
|
||||
* @param name attribute name
|
||||
* @param value attribute value
|
||||
*/
|
||||
public void setAttribute(String name, byte[] value);
|
||||
|
||||
/**
|
||||
* Gets an attribute
|
||||
* @param name attribute name
|
||||
* @return attribute value if attribute is set, <tt>null</tt> otherwise
|
||||
*/
|
||||
public byte[] getAttribute(String name);
|
||||
|
||||
/**
|
||||
* Gets all attributes
|
||||
* @return unmodifiable map of all attributes
|
||||
*/
|
||||
public Map<String, byte[]> getAttributesMap();
|
||||
}
|
|
@ -24,20 +24,13 @@ import org.apache.hadoop.hbase.HConstants;
|
|||
import org.apache.hadoop.hbase.KeyValue;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.apache.hadoop.io.Writable;
|
||||
import org.apache.hadoop.io.WritableUtils;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Used to perform Delete operations on a single row.
|
||||
|
@ -71,21 +64,10 @@ import java.util.UUID;
|
|||
* deleteFamily -- then you need to use the method overrides that take a
|
||||
* timestamp. The constructor timestamp is not referenced.
|
||||
*/
|
||||
public class Delete extends Operation
|
||||
public class Delete extends Mutation
|
||||
implements Writable, Row, Comparable<Row> {
|
||||
private static final byte DELETE_VERSION = (byte)3;
|
||||
|
||||
private byte [] row = null;
|
||||
// This ts is only used when doing a deleteRow. Anything less,
|
||||
private long ts;
|
||||
private long lockId = -1L;
|
||||
private boolean writeToWAL = true;
|
||||
private final Map<byte [], List<KeyValue>> familyMap =
|
||||
new TreeMap<byte [], List<KeyValue>>(Bytes.BYTES_COMPARATOR);
|
||||
|
||||
// a opaque blob that can be passed into a Delete.
|
||||
private Map<String, byte[]> attributes;
|
||||
|
||||
/** Constructor for Writable. DO NOT USE */
|
||||
public Delete() {
|
||||
this((byte [])null);
|
||||
|
@ -136,18 +118,6 @@ public class Delete extends Operation
|
|||
this.writeToWAL = d.writeToWAL;
|
||||
}
|
||||
|
||||
public int compareTo(final Row d) {
|
||||
return Bytes.compareTo(this.getRow(), d.getRow());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to check if the familyMap is empty
|
||||
* @return true if empty, false otherwise
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return familyMap.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all versions of all columns of the specified family.
|
||||
* <p>
|
||||
|
@ -245,47 +215,6 @@ public class Delete extends Operation
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the delete's familyMap
|
||||
* @return familyMap
|
||||
*/
|
||||
public Map<byte [], List<KeyValue>> getFamilyMap() {
|
||||
return this.familyMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the delete's row
|
||||
* @return row
|
||||
*/
|
||||
public byte [] getRow() {
|
||||
return this.row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the delete's RowLock
|
||||
* @return RowLock
|
||||
*/
|
||||
public RowLock getRowLock() {
|
||||
return new RowLock(this.row, this.lockId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the delete's lock ID.
|
||||
*
|
||||
* @return The lock ID.
|
||||
*/
|
||||
public long getLockId() {
|
||||
return this.lockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the delete's timestamp
|
||||
* @return timestamp
|
||||
*/
|
||||
public long getTimeStamp() {
|
||||
return this.ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timestamp of the delete.
|
||||
*
|
||||
|
@ -295,115 +224,12 @@ public class Delete extends Operation
|
|||
this.ts = timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets arbitrary delete's attribute.
|
||||
* In case value = null attribute is removed from the attributes map.
|
||||
* @param name attribute name
|
||||
* @param value attribute value
|
||||
*/
|
||||
public void setAttribute(String name, byte[] value) {
|
||||
if (attributes == null && value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<String, byte[]>();
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
attributes.remove(name);
|
||||
if (attributes.isEmpty()) {
|
||||
this.attributes = null;
|
||||
}
|
||||
} else {
|
||||
attributes.put(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets put's attribute
|
||||
* @param name attribute name
|
||||
* @return attribute value if attribute is set, <tt>null</tt> otherwise
|
||||
*/
|
||||
public byte[] getAttribute(String name) {
|
||||
if (attributes == null) {
|
||||
return null;
|
||||
}
|
||||
return attributes.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all scan's attributes
|
||||
* @return unmodifiable map of all attributes
|
||||
*/
|
||||
public Map<String, byte[]> getAttributesMap() {
|
||||
if (attributes == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return Collections.unmodifiableMap(attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the column family (i.e. schema) information
|
||||
* into a Map. Useful for parsing and aggregation by debugging,
|
||||
* logging, and administration tools.
|
||||
* @return Map
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getFingerprint() {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
List<String> families = new ArrayList<String>();
|
||||
// ideally, we would also include table information, but that information
|
||||
// is not stored in each Operation instance.
|
||||
map.put("families", families);
|
||||
for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) {
|
||||
families.add(Bytes.toStringBinary(entry.getKey()));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the details beyond the scope of getFingerprint (row, columns,
|
||||
* timestamps, etc.) into a Map along with the fingerprinted information.
|
||||
* Useful for debugging, logging, and administration tools.
|
||||
* @param maxCols a limit on the number of columns output prior to truncation
|
||||
* @return Map
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> toMap(int maxCols) {
|
||||
// we start with the fingerprint map and build on top of it.
|
||||
Map<String, Object> map = getFingerprint();
|
||||
// replace the fingerprint's simple list of families with a
|
||||
// map from column families to lists of qualifiers and kv details
|
||||
Map<String, List<Map<String, Object>>> columns =
|
||||
new HashMap<String, List<Map<String, Object>>>();
|
||||
map.put("families", columns);
|
||||
map.put("row", Bytes.toStringBinary(this.row));
|
||||
Map<String, Object> map = super.toMap(maxCols);
|
||||
// why is put not doing this?
|
||||
map.put("ts", this.ts);
|
||||
int colCount = 0;
|
||||
// iterate through all column families affected by this Delete
|
||||
for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) {
|
||||
// map from this family to details for each kv affected within the family
|
||||
List<Map<String, Object>> qualifierDetails =
|
||||
new ArrayList<Map<String, Object>>();
|
||||
columns.put(Bytes.toStringBinary(entry.getKey()), qualifierDetails);
|
||||
colCount += entry.getValue().size();
|
||||
if (maxCols <= 0) {
|
||||
continue;
|
||||
}
|
||||
// add details for each kv
|
||||
for (KeyValue kv : entry.getValue()) {
|
||||
if (--maxCols <= 0 ) {
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> kvMap = kv.toStringMap();
|
||||
// row and family information are already available in the bigger map
|
||||
kvMap.remove("row");
|
||||
kvMap.remove("family");
|
||||
qualifierDetails.add(kvMap);
|
||||
}
|
||||
}
|
||||
map.put("totalColumns", colCount);
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -433,15 +259,7 @@ public class Delete extends Operation
|
|||
this.familyMap.put(family, list);
|
||||
}
|
||||
if (version > 1) {
|
||||
int numAttributes = in.readInt();
|
||||
if (numAttributes > 0) {
|
||||
this.attributes = new HashMap<String, byte[]>();
|
||||
for(int i=0; i<numAttributes; i++) {
|
||||
String name = WritableUtils.readString(in);
|
||||
byte[] value = Bytes.readByteArray(in);
|
||||
this.attributes.put(name, value);
|
||||
}
|
||||
}
|
||||
readAttributes(in);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,15 +278,7 @@ public class Delete extends Operation
|
|||
kv.write(out);
|
||||
}
|
||||
}
|
||||
if (this.attributes == null) {
|
||||
out.writeInt(0);
|
||||
} else {
|
||||
out.writeInt(this.attributes.size());
|
||||
for (Map.Entry<String, byte[]> attr : this.attributes.entrySet()) {
|
||||
WritableUtils.writeString(out, attr.getKey());
|
||||
Bytes.writeByteArray(out, attr.getValue());
|
||||
}
|
||||
}
|
||||
writeAttributes(out);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -498,42 +308,4 @@ public class Delete extends Operation
|
|||
this.deleteColumn(parts[0], parts[1], HConstants.LATEST_TIMESTAMP);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if edits should be applied to WAL, false if not
|
||||
*/
|
||||
public boolean getWriteToWAL() {
|
||||
return this.writeToWAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this Delete should be written to the WAL or not.
|
||||
* Not writing the WAL means you may lose edits on server crash.
|
||||
* @param write true if edits should be written to WAL, false if not
|
||||
*/
|
||||
public void setWriteToWAL(boolean write) {
|
||||
this.writeToWAL = write;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the replication custer id.
|
||||
* @param clusterId
|
||||
*/
|
||||
public void setClusterId(UUID clusterId) {
|
||||
byte[] val = new byte[2*Bytes.SIZEOF_LONG];
|
||||
Bytes.putLong(val, 0, clusterId.getMostSignificantBits());
|
||||
Bytes.putLong(val, Bytes.SIZEOF_LONG, clusterId.getLeastSignificantBits());
|
||||
setAttribute(HConstants.CLUSTER_ID_ATTR, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The replication cluster id.
|
||||
*/
|
||||
public UUID getClusterId() {
|
||||
byte[] attr = getAttribute(HConstants.CLUSTER_ID_ATTR);
|
||||
if (attr == null) {
|
||||
return HConstants.DEFAULT_CLUSTER_ID;
|
||||
}
|
||||
return new UUID(Bytes.toLong(attr,0), Bytes.toLong(attr, Bytes.SIZEOF_LONG));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,13 +26,11 @@ import org.apache.hadoop.hbase.io.TimeRange;
|
|||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.apache.hadoop.io.Writable;
|
||||
import org.apache.hadoop.io.WritableFactories;
|
||||
import org.apache.hadoop.io.WritableUtils;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -65,7 +63,7 @@ import java.util.TreeSet;
|
|||
* <p>
|
||||
* To add a filter, execute {@link #setFilter(Filter) setFilter}.
|
||||
*/
|
||||
public class Get extends Operation
|
||||
public class Get extends OperationWithAttributes
|
||||
implements Writable, Row, Comparable<Row> {
|
||||
private static final byte GET_VERSION = (byte)2;
|
||||
|
||||
|
@ -77,7 +75,6 @@ public class Get extends Operation
|
|||
private TimeRange tr = new TimeRange();
|
||||
private Map<byte [], NavigableSet<byte []>> familyMap =
|
||||
new TreeMap<byte [], NavigableSet<byte []>>(Bytes.BYTES_COMPARATOR);
|
||||
private Map<String, byte[]> attributes;
|
||||
|
||||
/** Constructor for Writable. DO NOT USE */
|
||||
public Get() {}
|
||||
|
@ -306,54 +303,6 @@ public class Get extends Operation
|
|||
return this.familyMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets arbitrary get's attribute.
|
||||
* In case value = null attribute is removed from the attributes map.
|
||||
* @param name attribute name
|
||||
* @param value attribute value
|
||||
*/
|
||||
public void setAttribute(String name, byte[] value) {
|
||||
if (attributes == null && value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<String, byte[]>();
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
attributes.remove(name);
|
||||
if (attributes.isEmpty()) {
|
||||
this.attributes = null;
|
||||
}
|
||||
} else {
|
||||
attributes.put(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets get's attribute
|
||||
* @param name attribute name
|
||||
* @return attribute value if attribute is set, <tt>null</tt> otherwise
|
||||
*/
|
||||
public byte[] getAttribute(String name) {
|
||||
if (attributes == null) {
|
||||
return null;
|
||||
}
|
||||
return attributes.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all scan's attributes
|
||||
* @return unmodifiable map of all attributes
|
||||
*/
|
||||
public Map<String, byte[]> getAttributesMap() {
|
||||
if (attributes == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return Collections.unmodifiableMap(attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the table and column family (i.e. schema) information
|
||||
* into a String. Useful for parsing and aggregation by debugging,
|
||||
|
@ -462,15 +411,7 @@ public class Get extends Operation
|
|||
}
|
||||
this.familyMap.put(family, set);
|
||||
}
|
||||
int numAttributes = in.readInt();
|
||||
if (numAttributes > 0) {
|
||||
this.attributes = new HashMap<String, byte[]>();
|
||||
for(int i=0; i<numAttributes; i++) {
|
||||
String name = WritableUtils.readString(in);
|
||||
byte[] value = Bytes.readByteArray(in);
|
||||
this.attributes.put(name, value);
|
||||
}
|
||||
}
|
||||
readAttributes(in);
|
||||
}
|
||||
|
||||
public void write(final DataOutput out)
|
||||
|
@ -503,15 +444,7 @@ public class Get extends Operation
|
|||
}
|
||||
}
|
||||
}
|
||||
if (this.attributes == null) {
|
||||
out.writeInt(0);
|
||||
} else {
|
||||
out.writeInt(this.attributes.size());
|
||||
for (Map.Entry<String, byte[]> attr : this.attributes.entrySet()) {
|
||||
WritableUtils.writeString(out, attr.getKey());
|
||||
Bytes.writeByteArray(out, attr.getValue());
|
||||
}
|
||||
}
|
||||
writeAttributes(out);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Copyright 2011 The Apache Software Foundation
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.hadoop.hbase.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.hadoop.hbase.HConstants;
|
||||
import org.apache.hadoop.hbase.KeyValue;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
|
||||
public abstract class Mutation extends OperationWithAttributes {
|
||||
protected byte [] row = null;
|
||||
protected long ts = HConstants.LATEST_TIMESTAMP;
|
||||
protected long lockId = -1L;
|
||||
protected boolean writeToWAL = true;
|
||||
protected Map<byte [], List<KeyValue>> familyMap =
|
||||
new TreeMap<byte [], List<KeyValue>>(Bytes.BYTES_COMPARATOR);
|
||||
|
||||
/**
|
||||
* Compile the column family (i.e. schema) information
|
||||
* into a Map. Useful for parsing and aggregation by debugging,
|
||||
* logging, and administration tools.
|
||||
* @return Map
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getFingerprint() {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
List<String> families = new ArrayList<String>();
|
||||
// ideally, we would also include table information, but that information
|
||||
// is not stored in each Operation instance.
|
||||
map.put("families", families);
|
||||
for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) {
|
||||
families.add(Bytes.toStringBinary(entry.getKey()));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the details beyond the scope of getFingerprint (row, columns,
|
||||
* timestamps, etc.) into a Map along with the fingerprinted information.
|
||||
* Useful for debugging, logging, and administration tools.
|
||||
* @param maxCols a limit on the number of columns output prior to truncation
|
||||
* @return Map
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> toMap(int maxCols) {
|
||||
// we start with the fingerprint map and build on top of it.
|
||||
Map<String, Object> map = getFingerprint();
|
||||
// replace the fingerprint's simple list of families with a
|
||||
// map from column families to lists of qualifiers and kv details
|
||||
Map<String, List<Map<String, Object>>> columns =
|
||||
new HashMap<String, List<Map<String, Object>>>();
|
||||
map.put("families", columns);
|
||||
map.put("row", Bytes.toStringBinary(this.row));
|
||||
int colCount = 0;
|
||||
// iterate through all column families affected
|
||||
for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) {
|
||||
// map from this family to details for each kv affected within the family
|
||||
List<Map<String, Object>> qualifierDetails =
|
||||
new ArrayList<Map<String, Object>>();
|
||||
columns.put(Bytes.toStringBinary(entry.getKey()), qualifierDetails);
|
||||
colCount += entry.getValue().size();
|
||||
if (maxCols <= 0) {
|
||||
continue;
|
||||
}
|
||||
// add details for each kv
|
||||
for (KeyValue kv : entry.getValue()) {
|
||||
if (--maxCols <= 0 ) {
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> kvMap = kv.toStringMap();
|
||||
// row and family information are already available in the bigger map
|
||||
kvMap.remove("row");
|
||||
kvMap.remove("family");
|
||||
qualifierDetails.add(kvMap);
|
||||
}
|
||||
}
|
||||
map.put("totalColumns", colCount);
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if edits should be applied to WAL, false if not
|
||||
*/
|
||||
public boolean getWriteToWAL() {
|
||||
return this.writeToWAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this Delete should be written to the WAL or not.
|
||||
* Not writing the WAL means you may lose edits on server crash.
|
||||
* @param write true if edits should be written to WAL, false if not
|
||||
*/
|
||||
public void setWriteToWAL(boolean write) {
|
||||
this.writeToWAL = write;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the put's familyMap
|
||||
* @return familyMap
|
||||
*/
|
||||
public Map<byte [], List<KeyValue>> getFamilyMap() {
|
||||
return this.familyMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to check if the familyMap is empty
|
||||
* @return true if empty, false otherwise
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return familyMap.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the delete's row
|
||||
* @return row
|
||||
*/
|
||||
public byte [] getRow() {
|
||||
return this.row;
|
||||
}
|
||||
|
||||
public int compareTo(final Row d) {
|
||||
return Bytes.compareTo(this.getRow(), d.getRow());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the delete's RowLock
|
||||
* @return RowLock
|
||||
*/
|
||||
public RowLock getRowLock() {
|
||||
return new RowLock(this.row, this.lockId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the delete's lock ID.
|
||||
*
|
||||
* @return The lock ID.
|
||||
*/
|
||||
public long getLockId() {
|
||||
return this.lockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the timestamp
|
||||
* @return timestamp
|
||||
*/
|
||||
public long getTimeStamp() {
|
||||
return this.ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the replication custer id.
|
||||
* @param clusterId
|
||||
*/
|
||||
public void setClusterId(UUID clusterId) {
|
||||
byte[] val = new byte[2*Bytes.SIZEOF_LONG];
|
||||
Bytes.putLong(val, 0, clusterId.getMostSignificantBits());
|
||||
Bytes.putLong(val, Bytes.SIZEOF_LONG, clusterId.getLeastSignificantBits());
|
||||
setAttribute(HConstants.CLUSTER_ID_ATTR, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The replication cluster id.
|
||||
*/
|
||||
public UUID getClusterId() {
|
||||
byte[] attr = getAttribute(HConstants.CLUSTER_ID_ATTR);
|
||||
if (attr == null) {
|
||||
return HConstants.DEFAULT_CLUSTER_ID;
|
||||
}
|
||||
return new UUID(Bytes.toLong(attr,0), Bytes.toLong(attr, Bytes.SIZEOF_LONG));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright 2011 The Apache Software Foundation
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.hadoop.hbase.client;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.apache.hadoop.hbase.util.ClassSize;
|
||||
import org.apache.hadoop.io.WritableUtils;
|
||||
|
||||
public abstract class OperationWithAttributes extends Operation implements Attributes {
|
||||
// a opaque blob of attributes
|
||||
private Map<String, byte[]> attributes;
|
||||
|
||||
public void setAttribute(String name, byte[] value) {
|
||||
if (attributes == null && value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<String, byte[]>();
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
attributes.remove(name);
|
||||
if (attributes.isEmpty()) {
|
||||
this.attributes = null;
|
||||
}
|
||||
} else {
|
||||
attributes.put(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getAttribute(String name) {
|
||||
if (attributes == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return attributes.get(name);
|
||||
}
|
||||
|
||||
public Map<String, byte[]> getAttributesMap() {
|
||||
if (attributes == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return Collections.unmodifiableMap(attributes);
|
||||
}
|
||||
|
||||
protected long getAttributeSize() {
|
||||
long size = 0;
|
||||
if (attributes != null) {
|
||||
size += ClassSize.align(this.attributes.size() * ClassSize.MAP_ENTRY);
|
||||
for(Map.Entry<String, byte[]> entry : this.attributes.entrySet()) {
|
||||
size += ClassSize.align(ClassSize.STRING + entry.getKey().length());
|
||||
size += ClassSize.align(ClassSize.ARRAY + entry.getValue().length);
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
protected void writeAttributes(final DataOutput out) throws IOException {
|
||||
if (this.attributes == null) {
|
||||
out.writeInt(0);
|
||||
} else {
|
||||
out.writeInt(this.attributes.size());
|
||||
for (Map.Entry<String, byte[]> attr : this.attributes.entrySet()) {
|
||||
WritableUtils.writeString(out, attr.getKey());
|
||||
Bytes.writeByteArray(out, attr.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void readAttributes(final DataInput in) throws IOException {
|
||||
int numAttributes = in.readInt();
|
||||
if (numAttributes > 0) {
|
||||
this.attributes = new HashMap<String, byte[]>();
|
||||
for(int i=0; i<numAttributes; i++) {
|
||||
String name = WritableUtils.readString(in);
|
||||
byte[] value = Bytes.readByteArray(in);
|
||||
this.attributes.put(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,22 +26,15 @@ import org.apache.hadoop.hbase.io.HeapSize;
|
|||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.apache.hadoop.hbase.util.ClassSize;
|
||||
import org.apache.hadoop.io.Writable;
|
||||
import org.apache.hadoop.io.WritableUtils;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
/**
|
||||
* Used to perform Put operations for a single row.
|
||||
|
@ -50,21 +43,10 @@ import java.util.UUID;
|
|||
* for each column to be inserted, execute {@link #add(byte[], byte[], byte[]) add} or
|
||||
* {@link #add(byte[], byte[], long, byte[]) add} if setting the timestamp.
|
||||
*/
|
||||
public class Put extends Operation
|
||||
public class Put extends Mutation
|
||||
implements HeapSize, Writable, Row, Comparable<Row> {
|
||||
private static final byte PUT_VERSION = (byte)2;
|
||||
|
||||
private byte [] row = null;
|
||||
private long timestamp = HConstants.LATEST_TIMESTAMP;
|
||||
private long lockId = -1L;
|
||||
private boolean writeToWAL = true;
|
||||
|
||||
private Map<byte [], List<KeyValue>> familyMap =
|
||||
new TreeMap<byte [], List<KeyValue>>(Bytes.BYTES_COMPARATOR);
|
||||
|
||||
// a opaque blob that can be passed into a Put.
|
||||
private Map<String, byte[]> attributes;
|
||||
|
||||
private static final long OVERHEAD = ClassSize.align(
|
||||
ClassSize.OBJECT + 2 * ClassSize.REFERENCE +
|
||||
2 * Bytes.SIZEOF_LONG + Bytes.SIZEOF_BOOLEAN +
|
||||
|
@ -111,7 +93,7 @@ public class Put extends Operation
|
|||
throw new IllegalArgumentException("Row key is invalid");
|
||||
}
|
||||
this.row = Arrays.copyOf(row, row.length);
|
||||
this.timestamp = ts;
|
||||
this.ts = ts;
|
||||
if(rowLock != null) {
|
||||
this.lockId = rowLock.getLockId();
|
||||
}
|
||||
|
@ -122,7 +104,7 @@ public class Put extends Operation
|
|||
* @param putToCopy put to copy
|
||||
*/
|
||||
public Put(Put putToCopy) {
|
||||
this(putToCopy.getRow(), putToCopy.timestamp, putToCopy.getRowLock());
|
||||
this(putToCopy.getRow(), putToCopy.ts, putToCopy.getRowLock());
|
||||
this.familyMap =
|
||||
new TreeMap<byte [], List<KeyValue>>(Bytes.BYTES_COMPARATOR);
|
||||
for(Map.Entry<byte [], List<KeyValue>> entry :
|
||||
|
@ -140,7 +122,7 @@ public class Put extends Operation
|
|||
* @return this
|
||||
*/
|
||||
public Put add(byte [] family, byte [] qualifier, byte [] value) {
|
||||
return add(family, qualifier, this.timestamp, value);
|
||||
return add(family, qualifier, this.ts, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -207,7 +189,7 @@ public class Put extends Operation
|
|||
* existing KeyValue object in the family map.
|
||||
*/
|
||||
public boolean has(byte [] family, byte [] qualifier) {
|
||||
return has(family, qualifier, this.timestamp, new byte[0], true, true);
|
||||
return has(family, qualifier, this.ts, new byte[0], true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -237,7 +219,7 @@ public class Put extends Operation
|
|||
* existing KeyValue object in the family map.
|
||||
*/
|
||||
public boolean has(byte [] family, byte [] qualifier, byte [] value) {
|
||||
return has(family, qualifier, this.timestamp, value, true, false);
|
||||
return has(family, qualifier, this.ts, value, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -336,53 +318,6 @@ public class Put extends Operation
|
|||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the put's familyMap
|
||||
* @return familyMap
|
||||
*/
|
||||
public Map<byte [], List<KeyValue>> getFamilyMap() {
|
||||
return this.familyMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the put's row
|
||||
* @return row
|
||||
*/
|
||||
public byte [] getRow() {
|
||||
return this.row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the put's RowLock
|
||||
* @return RowLock
|
||||
*/
|
||||
public RowLock getRowLock() {
|
||||
return new RowLock(this.row, this.lockId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for retrieving the put's lockId
|
||||
* @return lockId
|
||||
*/
|
||||
public long getLockId() {
|
||||
return this.lockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to check if the familyMap is empty
|
||||
* @return true if empty, false otherwise
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return familyMap.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Timestamp
|
||||
*/
|
||||
public long getTimeStamp() {
|
||||
return this.timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of different families included in this put
|
||||
*/
|
||||
|
@ -401,138 +336,6 @@ public class Put extends Operation
|
|||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if edits should be applied to WAL, false if not
|
||||
*/
|
||||
public boolean getWriteToWAL() {
|
||||
return this.writeToWAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this Put should be written to the WAL or not.
|
||||
* Not writing the WAL means you may lose edits on server crash.
|
||||
* @param write true if edits should be written to WAL, false if not
|
||||
*/
|
||||
public void setWriteToWAL(boolean write) {
|
||||
this.writeToWAL = write;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets arbitrary put's attribute.
|
||||
* In case value = null attribute is removed from the attributes map.
|
||||
* @param name attribute name
|
||||
* @param value attribute value
|
||||
*/
|
||||
public void setAttribute(String name, byte[] value) {
|
||||
if (attributes == null && value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<String, byte[]>();
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
attributes.remove(name);
|
||||
if (attributes.isEmpty()) {
|
||||
this.attributes = null;
|
||||
}
|
||||
} else {
|
||||
attributes.put(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets put's attribute
|
||||
* @param name attribute name
|
||||
* @return attribute value if attribute is set, <tt>null</tt> otherwise
|
||||
*/
|
||||
public byte[] getAttribute(String name) {
|
||||
if (attributes == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return attributes.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all scan's attributes
|
||||
* @return unmodifiable map of all attributes
|
||||
*/
|
||||
public Map<String, byte[]> getAttributesMap() {
|
||||
if (attributes == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return Collections.unmodifiableMap(attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the column family (i.e. schema) information
|
||||
* into a Map. Useful for parsing and aggregation by debugging,
|
||||
* logging, and administration tools.
|
||||
* @return Map
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getFingerprint() {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
List<String> families = new ArrayList<String>();
|
||||
// ideally, we would also include table information, but that information
|
||||
// is not stored in each Operation instance.
|
||||
map.put("families", families);
|
||||
for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) {
|
||||
families.add(Bytes.toStringBinary(entry.getKey()));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the details beyond the scope of getFingerprint (row, columns,
|
||||
* timestamps, etc.) into a Map along with the fingerprinted information.
|
||||
* Useful for debugging, logging, and administration tools.
|
||||
* @param maxCols a limit on the number of columns output prior to truncation
|
||||
* @return Map
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> toMap(int maxCols) {
|
||||
// we start with the fingerprint map and build on top of it.
|
||||
Map<String, Object> map = getFingerprint();
|
||||
// replace the fingerprint's simple list of families with a
|
||||
// map from column families to lists of qualifiers and kv details
|
||||
Map<String, List<Map<String, Object>>> columns =
|
||||
new HashMap<String, List<Map<String, Object>>>();
|
||||
map.put("families", columns);
|
||||
map.put("row", Bytes.toStringBinary(this.row));
|
||||
int colCount = 0;
|
||||
// iterate through all column families affected by this Put
|
||||
for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) {
|
||||
// map from this family to details for each kv affected within the family
|
||||
List<Map<String, Object>> qualifierDetails =
|
||||
new ArrayList<Map<String, Object>>();
|
||||
columns.put(Bytes.toStringBinary(entry.getKey()), qualifierDetails);
|
||||
colCount += entry.getValue().size();
|
||||
if (maxCols <= 0) {
|
||||
continue;
|
||||
}
|
||||
// add details for each kv
|
||||
for (KeyValue kv : entry.getValue()) {
|
||||
if (--maxCols <= 0 ) {
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> kvMap = kv.toStringMap();
|
||||
// row and family information are already available in the bigger map
|
||||
kvMap.remove("row");
|
||||
kvMap.remove("family");
|
||||
qualifierDetails.add(kvMap);
|
||||
}
|
||||
}
|
||||
map.put("totalColumns", colCount);
|
||||
return map;
|
||||
}
|
||||
|
||||
public int compareTo(Row p) {
|
||||
return Bytes.compareTo(this.getRow(), p.getRow());
|
||||
}
|
||||
|
||||
//HeapSize
|
||||
public long heapSize() {
|
||||
long heapsize = OVERHEAD;
|
||||
|
@ -559,13 +362,8 @@ public class Put extends Operation
|
|||
heapsize += kv.heapSize();
|
||||
}
|
||||
}
|
||||
if (attributes != null) {
|
||||
heapsize += ClassSize.align(this.attributes.size() * ClassSize.MAP_ENTRY);
|
||||
for(Map.Entry<String, byte[]> entry : this.attributes.entrySet()) {
|
||||
heapsize += ClassSize.align(ClassSize.STRING + entry.getKey().length());
|
||||
heapsize += ClassSize.align(ClassSize.ARRAY + entry.getValue().length);
|
||||
}
|
||||
}
|
||||
heapsize += getAttributeSize();
|
||||
|
||||
return ClassSize.align((int)heapsize);
|
||||
}
|
||||
|
||||
|
@ -577,7 +375,7 @@ public class Put extends Operation
|
|||
throw new IOException("version not supported");
|
||||
}
|
||||
this.row = Bytes.readByteArray(in);
|
||||
this.timestamp = in.readLong();
|
||||
this.ts = in.readLong();
|
||||
this.lockId = in.readLong();
|
||||
this.writeToWAL = in.readBoolean();
|
||||
int numFamilies = in.readInt();
|
||||
|
@ -598,15 +396,7 @@ public class Put extends Operation
|
|||
this.familyMap.put(family, keys);
|
||||
}
|
||||
if (version > 1) {
|
||||
int numAttributes = in.readInt();
|
||||
if (numAttributes > 0) {
|
||||
this.attributes = new HashMap<String, byte[]>();
|
||||
for(int i=0; i<numAttributes; i++) {
|
||||
String name = WritableUtils.readString(in);
|
||||
byte[] value = Bytes.readByteArray(in);
|
||||
this.attributes.put(name, value);
|
||||
}
|
||||
}
|
||||
readAttributes(in);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -614,7 +404,7 @@ public class Put extends Operation
|
|||
throws IOException {
|
||||
out.writeByte(PUT_VERSION);
|
||||
Bytes.writeByteArray(out, this.row);
|
||||
out.writeLong(this.timestamp);
|
||||
out.writeLong(this.ts);
|
||||
out.writeLong(this.lockId);
|
||||
out.writeBoolean(this.writeToWAL);
|
||||
out.writeInt(familyMap.size());
|
||||
|
@ -632,15 +422,7 @@ public class Put extends Operation
|
|||
out.write(kv.getBuffer(), kv.getOffset(), kv.getLength());
|
||||
}
|
||||
}
|
||||
if (this.attributes == null) {
|
||||
out.writeInt(0);
|
||||
} else {
|
||||
out.writeInt(this.attributes.size());
|
||||
for (Map.Entry<String, byte[]> attr : this.attributes.entrySet()) {
|
||||
WritableUtils.writeString(out, attr.getKey());
|
||||
Bytes.writeByteArray(out, attr.getValue());
|
||||
}
|
||||
}
|
||||
writeAttributes(out);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -657,26 +439,4 @@ public class Put extends Operation
|
|||
byte [][] parts = KeyValue.parseColumn(column);
|
||||
return add(parts[0], parts[1], ts, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the replication custer id.
|
||||
* @param clusterId
|
||||
*/
|
||||
public void setClusterId(UUID clusterId) {
|
||||
byte[] val = new byte[2*Bytes.SIZEOF_LONG];
|
||||
Bytes.putLong(val, 0, clusterId.getMostSignificantBits());
|
||||
Bytes.putLong(val, Bytes.SIZEOF_LONG, clusterId.getLeastSignificantBits());
|
||||
setAttribute(HConstants.CLUSTER_ID_ATTR, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The replication cluster id.
|
||||
*/
|
||||
public UUID getClusterId() {
|
||||
byte[] attr = getAttribute(HConstants.CLUSTER_ID_ATTR);
|
||||
if (attr == null) {
|
||||
return HConstants.DEFAULT_CLUSTER_ID;
|
||||
}
|
||||
return new UUID(Bytes.toLong(attr,0), Bytes.toLong(attr, Bytes.SIZEOF_LONG));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,13 +29,11 @@ import org.apache.hadoop.hbase.io.TimeRange;
|
|||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.apache.hadoop.io.Writable;
|
||||
import org.apache.hadoop.io.WritableFactories;
|
||||
import org.apache.hadoop.io.WritableUtils;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -83,13 +81,12 @@ import java.util.TreeSet;
|
|||
* Expert: To explicitly disable server-side block caching for this scan,
|
||||
* execute {@link #setCacheBlocks(boolean)}.
|
||||
*/
|
||||
public class Scan extends Operation implements Writable {
|
||||
public class Scan extends OperationWithAttributes implements Writable {
|
||||
private static final byte SCAN_VERSION = (byte)2;
|
||||
private byte [] startRow = HConstants.EMPTY_START_ROW;
|
||||
private byte [] stopRow = HConstants.EMPTY_END_ROW;
|
||||
private int maxVersions = 1;
|
||||
private int batch = -1;
|
||||
private Map<String, byte[]> attributes;
|
||||
|
||||
/*
|
||||
* -1 means no caching
|
||||
|
@ -446,55 +443,6 @@ public class Scan extends Operation implements Writable {
|
|||
return cacheBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets arbitrary scan's attribute.
|
||||
* In case value = null attribute is removed from the attributes map.
|
||||
* @param name attribute name
|
||||
* @param value attribute value
|
||||
*/
|
||||
public void setAttribute(String name, byte[] value) {
|
||||
if (attributes == null && value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<String, byte[]>();
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
attributes.remove(name);
|
||||
if (attributes.isEmpty()) {
|
||||
this.attributes = null;
|
||||
}
|
||||
} else {
|
||||
attributes.put(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets scan's attribute
|
||||
* @param name attribute name
|
||||
* @return attribute value if attribute is set, <tt>null</tt> otherwise
|
||||
*/
|
||||
public byte[] getAttribute(String name) {
|
||||
if (attributes == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return attributes.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all scan's attributes
|
||||
* @return unmodifiable map of all attributes
|
||||
*/
|
||||
public Map<String, byte[]> getAttributesMap() {
|
||||
if (attributes == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return Collections.unmodifiableMap(attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the table and column family (i.e. schema) information
|
||||
* into a String. Useful for parsing and aggregation by debugging,
|
||||
|
@ -616,15 +564,7 @@ public class Scan extends Operation implements Writable {
|
|||
}
|
||||
|
||||
if (version > 1) {
|
||||
int numAttributes = in.readInt();
|
||||
if (numAttributes > 0) {
|
||||
this.attributes = new HashMap<String, byte[]>();
|
||||
for(int i=0; i<numAttributes; i++) {
|
||||
String name = WritableUtils.readString(in);
|
||||
byte[] value = Bytes.readByteArray(in);
|
||||
this.attributes.put(name, value);
|
||||
}
|
||||
}
|
||||
readAttributes(in);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -658,16 +598,7 @@ public class Scan extends Operation implements Writable {
|
|||
out.writeInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.attributes == null) {
|
||||
out.writeInt(0);
|
||||
} else {
|
||||
out.writeInt(this.attributes.size());
|
||||
for (Map.Entry<String, byte[]> attr : this.attributes.entrySet()) {
|
||||
WritableUtils.writeString(out, attr.getKey());
|
||||
Bytes.writeByteArray(out, attr.getValue());
|
||||
}
|
||||
}
|
||||
writeAttributes(out);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue