From 67047d7ec72d363155b5c088f4798db92c34a812 Mon Sep 17 00:00:00 2001 From: Michael Stack Date: Tue, 24 Nov 2009 20:26:34 +0000 Subject: [PATCH] HBASE-1987 The Put object has no simple read methods for checking what has already been added git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@883853 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 2 + .../org/apache/hadoop/hbase/client/Put.java | 168 ++++++++++++++++-- 2 files changed, 160 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 7baad34b22a..917763312de 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -200,6 +200,8 @@ Release 0.21.0 - Unreleased HBASE-1971 Unit test the full WAL replay cycle HBASE-1970 Export does one version only; make it configurable how many it does + HBASE-1987 The Put object has no simple read methods for checking what + has already been added (Ryan Smith via Stack) NEW FEATURES HBASE-1901 "General" partitioner for "hbase-48" bulk (behind the api, write diff --git a/src/java/org/apache/hadoop/hbase/client/Put.java b/src/java/org/apache/hadoop/hbase/client/Put.java index 2a50e068f43..1ef3acb162a 100644 --- a/src/java/org/apache/hadoop/hbase/client/Put.java +++ b/src/java/org/apache/hadoop/hbase/client/Put.java @@ -132,12 +132,8 @@ public class Put implements HeapSize, Writable, Row, Comparable { * @param value column value */ public Put add(byte [] family, byte [] qualifier, long ts, byte [] value) { - List list = familyMap.get(family); - if(list == null) { - list = new ArrayList(0); - } - KeyValue kv = new KeyValue(this.row, family, qualifier, ts, - KeyValue.Type.Put, value); + List list = getKeyValueList(family); + KeyValue kv = createPutKeyValue(family, qualifier, ts, value); list.add(kv); familyMap.put(kv.getFamily(), list); return this; @@ -151,10 +147,7 @@ public class Put implements HeapSize, Writable, Row, Comparable { */ public Put add(KeyValue kv) throws IOException{ byte [] family = kv.getFamily(); - List list = familyMap.get(family); - if(list == null) { - list = new ArrayList(); - } + List list = getKeyValueList(family); //Checking that the row of the kv is the same as the put int res = Bytes.compareTo(this.row, 0, row.length, kv.getBuffer(), kv.getRowOffset(), kv.getRowLength()); @@ -168,7 +161,162 @@ public class Put implements HeapSize, Writable, Row, Comparable { familyMap.put(family, list); return this; } + + /** + * Create a KeyValue with this objects row key and the Put identifier. + * + * @param family + * @param qualifier + * @param ts + * @param value + * @return a KeyValue with this objects row key and the Put identifier. + */ + private KeyValue createPutKeyValue(byte[] family, byte[] qualifier, long ts, + byte[] value) { + return new KeyValue(this.row, family, qualifier, ts, KeyValue.Type.Put, + value); + } + /** + * A convenience method to determine if this object's familyMap contains + * a value assigned to the given family & qualifier. + * Both given arguments must match the KeyValue object to return true. + * + * @param family + * @param qualifier + * @return returns true if the given family and qualifier already has an + * 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); + } + + /** + * A convenience method to determine if this object's familyMap contains + * a value assigned to the given family, qualifier and timestamp. + * All 3 given arguments must match the KeyValue object to return true. + * + * @param family + * @param qualifier + * @param ts + * @return returns true if the given family, qualifier and timestamp already has an + * existing KeyValue object in the family map. + */ + public boolean has(byte [] family, byte [] qualifier, long ts) { + return has(family, qualifier, ts, new byte[0], false, true); + } + + /** + * A convenience method to determine if this object's familyMap contains + * a value assigned to the given family, qualifier and timestamp. + * All 3 given arguments must match the KeyValue object to return true. + * + * @param family + * @param qualifier + * @param value + * @return returns true if the given family, qualifier and value already has an + * 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); + } + + /** + * A convenience method to determine if this object's familyMap contains + * the given value assigned to the given family, qualifier and timestamp. + * All 4 given arguments must match the KeyValue object to return true. + * + * @param family + * @param qualifier + * @param ts + * @param value + * @return returns true if the given family, qualifier timestamp and value + * already has an existing KeyValue object in the family map. + */ + public boolean has(byte [] family, byte [] qualifier, long ts, byte [] value) { + return has(family, qualifier, ts, value, false, false); + } + + /** + * Private method to determine if this object's familyMap contains + * the given value assigned to the given family, qualifier and timestamp + * respecting the 2 boolean arguments + * + * @param family + * @param qualifier + * @param ts + * @param value + * @param ignoreTS + * @param ignoreValue + * @return returns true if the given family, qualifier timestamp and value + * already has an existing KeyValue object in the family map. + */ + private boolean has(byte [] family, byte [] qualifier, long ts, byte [] value, + boolean ignoreTS, boolean ignoreValue) { + List list = getKeyValueList(family); + if (list.size() == 0 ) { + return false; + } + if (!ignoreTS && !ignoreValue) { + KeyValue kv = createPutKeyValue(family, qualifier, ts, value); + return (list.contains(kv)); + } else if (ignoreValue) { + for (KeyValue kv: list) { + if (Arrays.equals(kv.getFamily(), family) && Arrays.equals(kv.getQualifier(), qualifier) + && kv.getTimestamp() == ts) { + return true; + } + } + } else if (ignoreTS) { + for (KeyValue kv: list) { + if (Arrays.equals(kv.getFamily(), family) && Arrays.equals(kv.getQualifier(), qualifier) + && Arrays.equals(kv.getValue(), value)) { + return true; + } + } + } else { + for (KeyValue kv: list) { + if (Arrays.equals(kv.getFamily(), family) && Arrays.equals( + kv.getQualifier(), qualifier)) { + return true; + } + } + } + return false; + } + + /** + * Returns a list of all KeyValue objects with matching column family and qualifier. + * + * @param family + * @param qualifier + * @return a list of KeyValue objects with the matching family and qualifier, + * returns an empty list if one doesnt exist for the given family. + */ + public List get(byte[] family, byte[] qualifier) { + List filteredList = new ArrayList(); + for (KeyValue kv: getKeyValueList(family)) { + if (Arrays.equals(kv.getQualifier(), qualifier)) { + filteredList.add(kv); + } + } + return filteredList; + } + + /** + * Creates an empty list if one doesnt exist for the given column family + * or else it returns the associated list of KeyValue objects. + * + * @param family + * @return a list of KeyValue objects, returns an empty list if one doesnt exist. + */ + private List getKeyValueList(byte[] family) { + List list = familyMap.get(family); + if(list == null) { + list = new ArrayList(0); + } + return list; + } /** * Method for retrieving the put's familyMap