From fd3bc7d8f6b0171a2dc388215a38bd4476a2bdac Mon Sep 17 00:00:00 2001
From: "Robert J. Moore" <Robert.J.Moore@allanbank.com>
Date: Sun, 8 Nov 2015 14:49:47 -0500
Subject: [PATCH] [hbase10] Checkstyle updates for HBase 1.0 binding.

---
 hbase10/pom.xml                               |  24 +
 .../java/com/yahoo/ycsb/db/HBaseClient10.java | 833 +++++++++---------
 .../java/com/yahoo/ycsb/db/package-info.java  |  23 +
 3 files changed, 452 insertions(+), 428 deletions(-)
 create mode 100644 hbase10/src/main/java/com/yahoo/ycsb/db/package-info.java

diff --git a/hbase10/pom.xml b/hbase10/pom.xml
index 8fffd494..62f5209f 100644
--- a/hbase10/pom.xml
+++ b/hbase10/pom.xml
@@ -53,4 +53,28 @@ LICENSE file.
       <scope>test</scope>
     </dependency>
   </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>2.15</version>
+        <configuration>
+          <consoleOutput>true</consoleOutput>
+          <configLocation>../checkstyle.xml</configLocation>
+          <failOnViolation>true</failOnViolation>
+          <failsOnError>true</failsOnError>
+        </configuration>
+        <executions>
+          <execution>
+            <id>validate</id>
+            <phase>validate</phase>
+            <goals>
+              <goal>checkstyle</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/hbase10/src/main/java/com/yahoo/ycsb/db/HBaseClient10.java b/hbase10/src/main/java/com/yahoo/ycsb/db/HBaseClient10.java
index d047b4aa..68b4e917 100644
--- a/hbase10/src/main/java/com/yahoo/ycsb/db/HBaseClient10.java
+++ b/hbase10/src/main/java/com/yahoo/ycsb/db/HBaseClient10.java
@@ -15,7 +15,6 @@
 
 package com.yahoo.ycsb.db;
 
-
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 
@@ -59,460 +58,438 @@ import java.util.Vector;
  * A modified version of HBaseClient (which targets HBase v0.9) utilizing the
  * HBase 1.0.0 API.
  *
- * This client also adds toggleable client-side buffering and configurable write durability.
+ * This client also adds toggleable client-side buffering and configurable write
+ * durability.
  */
-public class HBaseClient10 extends com.yahoo.ycsb.DB
-{
-    private Configuration config = HBaseConfiguration.create();
-
-    public boolean _debug=false;
-
-    public String _tableName="";
-    public Connection _connection=null;
-
-    // Depending on the value of _clientBuffering, either _bufferedMutator
-    // (_clientBuffering) or _hTable (!_clientBuffering) will be used.
-    public Table _table=null;
-    public BufferedMutator _bufferedMutator=null;
-
-    public String _columnFamily="";
-    public byte _columnFamilyBytes[];
-
-    /**
-     * Durability to use for puts and deletes.
-     */
-    public Durability _durability = Durability.USE_DEFAULT;
-
-    /** Whether or not a page filter should be used to limit scan length. */
-    public boolean _usePageFilter = true;
-
-    /**
-     * If true, buffer mutations on the client.
-     * This is the default behavior for HBaseClient. For measuring
-     * insert/update/delete latencies, client side buffering should be disabled.
-     */
-    public boolean _clientSideBuffering = false;
-    public long _writeBufferSize = 1024 * 1024 * 12;
-
-    public static final int HTTP_ERROR = -2;
-
-    /**
-     * Initialize any state for this DB.
-     * Called once per DB instance; there is one DB instance per client thread.
-     */
-    @Override
-    public void init() throws DBException
-    {
-        if ("true".equals(getProperties().getProperty("clientbuffering", "false"))) {
-            this._clientSideBuffering = true;
-        }
-        if (getProperties().containsKey("writebuffersize")) {
-            _writeBufferSize = Long.parseLong(getProperties().getProperty("writebuffersize"));
-        }
-
-        if (getProperties().getProperty("durability") != null) {
-            this._durability = Durability.valueOf(getProperties().getProperty("durability"));
-        }
-
-        try {
-            _connection = ConnectionFactory.createConnection(config);
-        } catch (java.io.IOException e) {
-            throw new DBException(e);
-        }
-
-        if ( (getProperties().getProperty("debug")!=null) &&
-                (getProperties().getProperty("debug").compareTo("true")==0) )
-        {
-            _debug=true;
-        }
-
-        if ("false".equals(getProperties().getProperty("hbase.usepagefilter", "true"))) {
-          _usePageFilter = false;
-        }
-
-        _columnFamily = getProperties().getProperty("columnfamily");
-        if (_columnFamily == null)
-        {
-            System.err.println("Error, must specify a columnfamily for HBase table");
-            throw new DBException("No columnfamily specified");
-        }
-        _columnFamilyBytes = Bytes.toBytes(_columnFamily);
-
-      // Terminate right now if table does not exist, since the client
-      // will not propagate this error upstream once the workload
-      // starts.
-      String table = com.yahoo.ycsb.workloads.CoreWorkload.table;
-      try
-	  {
-	      final TableName tableName = TableName.valueOf(table);
-	      HTableDescriptor dsc = _connection.getTable(tableName).getTableDescriptor();
-	  }
-      catch (IOException e)
-	  {
-	      throw new DBException(e);
-	  }
+public class HBaseClient10 extends com.yahoo.ycsb.DB {
+  private Configuration config = HBaseConfiguration.create();
+
+  private boolean debug = false;
+
+  private String tableName = "";
+  private Connection connection = null;
+
+  // Depending on the value of clientSideBuffering, either bufferedMutator
+  // (clientSideBuffering) or currentTable (!clientSideBuffering) will be used.
+  private Table currentTable = null;
+  private BufferedMutator bufferedMutator = null;
+
+  private String columnFamily = "";
+  private byte[] columnFamilyBytes;
+
+  /**
+   * Durability to use for puts and deletes.
+   */
+  private Durability durability = Durability.USE_DEFAULT;
+
+  /** Whether or not a page filter should be used to limit scan length. */
+  private boolean usePageFilter = true;
+
+  /**
+   * If true, buffer mutations on the client. This is the default behavior for
+   * HBaseClient. For measuring insert/update/delete latencies, client side
+   * buffering should be disabled.
+   */
+  private boolean clientSideBuffering = false;
+  private long writeBufferSize = 1024 * 1024 * 12;
+
+  /**
+   * Initialize any state for this DB. Called once per DB instance; there is one
+   * DB instance per client thread.
+   */
+  @Override
+  public void init() throws DBException {
+    if ("true"
+        .equals(getProperties().getProperty("clientbuffering", "false"))) {
+      this.clientSideBuffering = true;
     }
-
-    /**
-     * Cleanup any state for this DB.
-     * Called once per DB instance; there is one DB instance per client thread.
-     */
-    @Override
-    public void cleanup() throws DBException
-    {
-        // Get the measurements instance as this is the only client that should
-        // count clean up time like an update if client-side buffering is
-        // enabled.
-        Measurements _measurements = Measurements.getMeasurements();
-        try {
-            long st=System.nanoTime();
-            if (_bufferedMutator != null) {
-                _bufferedMutator.close();
-            }
-            if (_table != null) {
-                _table.close();
-            }
-            long en=System.nanoTime();
-            final String type = _clientSideBuffering ? "UPDATE" : "CLEANUP";
-            _measurements.measure(type, (int)((en-st)/1000));
-            _connection.close();
-        } catch (IOException e) {
-            throw new DBException(e);
-        }
+    if (getProperties().containsKey("writebuffersize")) {
+      writeBufferSize =
+          Long.parseLong(getProperties().getProperty("writebuffersize"));
     }
 
-    public void getHTable(String table) throws IOException
-    {
-        final TableName tableName = TableName.valueOf(table);
-        this._table = this._connection.getTable(tableName);
-        //suggestions from http://ryantwopointoh.blogspot.com/2009/01/performance-of-hbase-importing.html
-        if (_clientSideBuffering) {
-            final BufferedMutatorParams p = new BufferedMutatorParams(tableName);
-            p.writeBufferSize(_writeBufferSize);
-            this._bufferedMutator = this._connection.getBufferedMutator(p);
-        }
+    if (getProperties().getProperty("durability") != null) {
+      this.durability =
+          Durability.valueOf(getProperties().getProperty("durability"));
     }
 
-    /**
-     * Read a record from the database. Each field/value pair from the result will be stored in a HashMap.
-     *
-     * @param table The name of the table
-     * @param key The record key of the record to read.
-     * @param fields The list of fields to read, or null for all of them
-     * @param result A HashMap of field/value pairs for the result
-     * @return Zero on success, a non-zero error code on error
-     */
-    public Status read(String table, String key, Set<String> fields, HashMap<String,ByteIterator> result)
-    {
-        //if this is a "new" table, init HTable object.  Else, use existing one
-        if (!_tableName.equals(table)) {
-            _table = null;
-            try
-            {
-                getHTable(table);
-                _tableName = table;
-            }
-            catch (IOException e)
-            {
-                System.err.println("Error accessing HBase table: " + e);
-                return Status.ERROR;
-            }
-        }
-
-        Result r = null;
-        try
-        {
-            if (_debug) {
-                System.out.println("Doing read from HBase columnfamily "+_columnFamily);
-                System.out.println("Doing read for key: "+key);
-            }
-            Get g = new Get(Bytes.toBytes(key));
-            if (fields == null) {
-                g.addFamily(_columnFamilyBytes);
-            } else {
-                for (String field : fields) {
-                    g.addColumn(_columnFamilyBytes, Bytes.toBytes(field));
-                }
-            }
-            r = _table.get(g);
-        }
-        catch (IOException e)
-        {
-            if (_debug) {
-                System.err.println("Error doing get: "+e);
-            }
-            return Status.ERROR;
-        }
-        catch (ConcurrentModificationException e)
-        {
-            //do nothing for now...need to understand HBase concurrency model better
-            return Status.ERROR;
-        }
-
-        if (r.isEmpty()) {
-            return Status.NOT_FOUND;
-        }
-
-        while (r.advance()) {
-            final Cell c = r.current();
-            result.put(Bytes.toString(CellUtil.cloneQualifier(c)),
-                    new ByteArrayByteIterator(CellUtil.cloneValue(c)));
-            if (_debug) {
-                System.out.println("Result for field: "+Bytes.toString(CellUtil.cloneQualifier(c))+
-                        " is: "+Bytes.toString(CellUtil.cloneValue(c)));
-            }
-        }
-        return Status.OK;
+    try {
+      connection = ConnectionFactory.createConnection(config);
+    } catch (java.io.IOException e) {
+      throw new DBException(e);
     }
 
-    /**
-     * Perform a range scan for a set of records in the database. Each field/value pair from the result will be stored in a HashMap.
-     *
-     * @param table The name of the table
-     * @param startkey The record key of the first record to read.
-     * @param recordcount The number of records to read
-     * @param fields The list of fields to read, or null for all of them
-     * @param result A Vector of HashMaps, where each HashMap is a set field/value pairs for one record
-     * @return Zero on success, a non-zero error code on error
-     */
-    @Override
-    public Status scan(String table, String startkey, int recordcount, Set<String> fields, Vector<HashMap<String,ByteIterator>> result)
-    {
-        //if this is a "new" table, init HTable object.  Else, use existing one
-        if (!_tableName.equals(table)) {
-            _table = null;
-            try
-            {
-                getHTable(table);
-                _tableName = table;
-            }
-            catch (IOException e)
-            {
-                System.err.println("Error accessing HBase table: "+e);
-                return Status.ERROR;
-            }
-        }
-
-        Scan s = new Scan(Bytes.toBytes(startkey));
-        //HBase has no record limit.  Here, assume recordcount is small enough to bring back in one call.
-        //We get back recordcount records
-        s.setCaching(recordcount);
-        if (this._usePageFilter) {
-          s.setFilter(new PageFilter(recordcount));
-        }
-
-        //add specified fields or else all fields
-        if (fields == null)
-        {
-            s.addFamily(_columnFamilyBytes);
-        }
-        else
-        {
-            for (String field : fields)
-            {
-                s.addColumn(_columnFamilyBytes,Bytes.toBytes(field));
-            }
-        }
-
-        //get results
-        ResultScanner scanner = null;
-        try {
-            scanner = _table.getScanner(s);
-            int numResults = 0;
-            for (Result rr = scanner.next(); rr != null; rr = scanner.next())
-            {
-                //get row key
-                String key = Bytes.toString(rr.getRow());
-
-                if (_debug)
-                {
-                    System.out.println("Got scan result for key: "+key);
-                }
-
-                HashMap<String,ByteIterator> rowResult = new HashMap<String, ByteIterator>();
-
-                while (rr.advance()) {
-                    final Cell cell = rr.current();
-                    rowResult.put(
-                            Bytes.toString(CellUtil.cloneQualifier(cell)),
-                            new ByteArrayByteIterator(CellUtil.cloneValue(cell)));
-                }
-
-                //add rowResult to result vector
-                result.add(rowResult);
-                numResults++;
-
-                // PageFilter does not guarantee that the number of results is <= pageSize, so this
-                // break is required.
-                if (numResults >= recordcount) //if hit recordcount, bail out
-                {
-                    break;
-                }
-            } //done with row
-
-        }
+    if ((getProperties().getProperty("debug") != null)
+        && (getProperties().getProperty("debug").compareTo("true") == 0)) {
+      debug = true;
+    }
 
-        catch (IOException e) {
-            if (_debug)
-            {
-                System.out.println("Error in getting/parsing scan result: "+e);
-            }
-            return Status.ERROR;
-        }
+    if ("false"
+        .equals(getProperties().getProperty("hbase.usepagefilter", "true"))) {
+      usePageFilter = false;
+    }
 
-        finally {
-            if (scanner != null)
-            {
-                scanner.close();
-            }
-        }
+    columnFamily = getProperties().getProperty("columnfamily");
+    if (columnFamily == null) {
+      System.err.println("Error, must specify a columnfamily for HBase table");
+      throw new DBException("No columnfamily specified");
+    }
+    columnFamilyBytes = Bytes.toBytes(columnFamily);
+
+    // Terminate right now if table does not exist, since the client
+    // will not propagate this error upstream once the workload
+    // starts.
+    String table = com.yahoo.ycsb.workloads.CoreWorkload.table;
+    try {
+      final TableName tName = TableName.valueOf(table);
+      HTableDescriptor dsc =
+          connection.getTable(tName).getTableDescriptor();
+    } catch (IOException e) {
+      throw new DBException(e);
+    }
+  }
+
+  /**
+   * Cleanup any state for this DB. Called once per DB instance; there is one DB
+   * instance per client thread.
+   */
+  @Override
+  public void cleanup() throws DBException {
+    // Get the measurements instance as this is the only client that should
+    // count clean up time like an update if client-side buffering is
+    // enabled.
+    Measurements measurements = Measurements.getMeasurements();
+    try {
+      long st = System.nanoTime();
+      if (bufferedMutator != null) {
+        bufferedMutator.close();
+      }
+      if (currentTable != null) {
+        currentTable.close();
+      }
+      long en = System.nanoTime();
+      final String type = clientSideBuffering ? "UPDATE" : "CLEANUP";
+      measurements.measure(type, (int) ((en - st) / 1000));
+      connection.close();
+    } catch (IOException e) {
+      throw new DBException(e);
+    }
+  }
+
+  public void getHTable(String table) throws IOException {
+    final TableName tName = TableName.valueOf(table);
+    this.currentTable = this.connection.getTable(tName);
+    // suggestions from
+    // http://ryantwopointoh.blogspot.com/2009/01/
+    // performance-of-hbase-importing.html
+    if (clientSideBuffering) {
+      final BufferedMutatorParams p = new BufferedMutatorParams(tName);
+      p.writeBufferSize(writeBufferSize);
+      this.bufferedMutator = this.connection.getBufferedMutator(p);
+    }
+  }
+
+  /**
+   * Read a record from the database. Each field/value pair from the result will
+   * be stored in a HashMap.
+   *
+   * @param table
+   *          The name of the table
+   * @param key
+   *          The record key of the record to read.
+   * @param fields
+   *          The list of fields to read, or null for all of them
+   * @param result
+   *          A HashMap of field/value pairs for the result
+   * @return Zero on success, a non-zero error code on error
+   */
+  public Status read(String table, String key, Set<String> fields,
+      HashMap<String, ByteIterator> result) {
+    // if this is a "new" table, init HTable object. Else, use existing one
+    if (!tableName.equals(table)) {
+      currentTable = null;
+      try {
+        getHTable(table);
+        tableName = table;
+      } catch (IOException e) {
+        System.err.println("Error accessing HBase table: " + e);
+        return Status.ERROR;
+      }
+    }
 
-        return Status.OK;
+    Result r = null;
+    try {
+      if (debug) {
+        System.out
+            .println("Doing read from HBase columnfamily " + columnFamily);
+        System.out.println("Doing read for key: " + key);
+      }
+      Get g = new Get(Bytes.toBytes(key));
+      if (fields == null) {
+        g.addFamily(columnFamilyBytes);
+      } else {
+        for (String field : fields) {
+          g.addColumn(columnFamilyBytes, Bytes.toBytes(field));
+        }
+      }
+      r = currentTable.get(g);
+    } catch (IOException e) {
+      if (debug) {
+        System.err.println("Error doing get: " + e);
+      }
+      return Status.ERROR;
+    } catch (ConcurrentModificationException e) {
+      // do nothing for now...need to understand HBase concurrency model better
+      return Status.ERROR;
     }
 
-    /**
-     * Update a record in the database. Any field/value pairs in the specified values HashMap will be written into the record with the specified
-     * record key, overwriting any existing values with the same field name.
-     *
-     * @param table The name of the table
-     * @param key The record key of the record to write
-     * @param values A HashMap of field/value pairs to update in the record
-     * @return Zero on success, a non-zero error code on error
-     */
-    @Override
-    public Status update(String table, String key, HashMap<String,ByteIterator> values)
-    {
-        //if this is a "new" table, init HTable object.  Else, use existing one
-        if (!_tableName.equals(table)) {
-            _table = null;
-            try
-            {
-                getHTable(table);
-                _tableName = table;
-            }
-            catch (IOException e)
-            {
-                System.err.println("Error accessing HBase table: "+e);
-                return Status.ERROR;
-            }
-        }
+    if (r.isEmpty()) {
+      return Status.NOT_FOUND;
+    }
 
+    while (r.advance()) {
+      final Cell c = r.current();
+      result.put(Bytes.toString(CellUtil.cloneQualifier(c)),
+          new ByteArrayByteIterator(CellUtil.cloneValue(c)));
+      if (debug) {
+        System.out.println(
+            "Result for field: " + Bytes.toString(CellUtil.cloneQualifier(c))
+                + " is: " + Bytes.toString(CellUtil.cloneValue(c)));
+      }
+    }
+    return Status.OK;
+  }
+
+  /**
+   * Perform a range scan for a set of records in the database. Each field/value
+   * pair from the result will be stored in a HashMap.
+   *
+   * @param table
+   *          The name of the table
+   * @param startkey
+   *          The record key of the first record to read.
+   * @param recordcount
+   *          The number of records to read
+   * @param fields
+   *          The list of fields to read, or null for all of them
+   * @param result
+   *          A Vector of HashMaps, where each HashMap is a set field/value
+   *          pairs for one record
+   * @return Zero on success, a non-zero error code on error
+   */
+  @Override
+  public Status scan(String table, String startkey, int recordcount,
+      Set<String> fields, Vector<HashMap<String, ByteIterator>> result) {
+    // if this is a "new" table, init HTable object. Else, use existing one
+    if (!tableName.equals(table)) {
+      currentTable = null;
+      try {
+        getHTable(table);
+        tableName = table;
+      } catch (IOException e) {
+        System.err.println("Error accessing HBase table: " + e);
+        return Status.ERROR;
+      }
+    }
 
-        if (_debug) {
-            System.out.println("Setting up put for key: "+key);
-        }
-        Put p = new Put(Bytes.toBytes(key));
-        p.setDurability(_durability);
-        for (Map.Entry<String, ByteIterator> entry : values.entrySet())
-        {
-            byte[] value = entry.getValue().toArray();
-            if (_debug) {
-                System.out.println("Adding field/value " + entry.getKey() + "/"+
-                        Bytes.toStringBinary(value) + " to put request");
-            }
-            p.addColumn(_columnFamilyBytes,Bytes.toBytes(entry.getKey()), value);
-        }
+    Scan s = new Scan(Bytes.toBytes(startkey));
+    // HBase has no record limit. Here, assume recordcount is small enough to
+    // bring back in one call.
+    // We get back recordcount records
+    s.setCaching(recordcount);
+    if (this.usePageFilter) {
+      s.setFilter(new PageFilter(recordcount));
+    }
 
-        try
-        {
-            if (_clientSideBuffering) {
-                Preconditions.checkNotNull(_bufferedMutator);
-                _bufferedMutator.mutate(p);
-            } else{
-                _table.put(p);
-            }
-        }
-        catch (IOException e)
-        {
-            if (_debug) {
-                System.err.println("Error doing put: "+e);
-            }
-            return Status.ERROR;
-        }
-        catch (ConcurrentModificationException e)
-        {
-            //do nothing for now...hope this is rare
-            return Status.ERROR;
-        }
+    // add specified fields or else all fields
+    if (fields == null) {
+      s.addFamily(columnFamilyBytes);
+    } else {
+      for (String field : fields) {
+        s.addColumn(columnFamilyBytes, Bytes.toBytes(field));
+      }
+    }
 
-        return Status.OK;
+    // get results
+    ResultScanner scanner = null;
+    try {
+      scanner = currentTable.getScanner(s);
+      int numResults = 0;
+      for (Result rr = scanner.next(); rr != null; rr = scanner.next()) {
+        // get row key
+        String key = Bytes.toString(rr.getRow());
+
+        if (debug) {
+          System.out.println("Got scan result for key: " + key);
+        }
+
+        HashMap<String, ByteIterator> rowResult =
+            new HashMap<String, ByteIterator>();
+
+        while (rr.advance()) {
+          final Cell cell = rr.current();
+          rowResult.put(Bytes.toString(CellUtil.cloneQualifier(cell)),
+              new ByteArrayByteIterator(CellUtil.cloneValue(cell)));
+        }
+
+        // add rowResult to result vector
+        result.add(rowResult);
+        numResults++;
+
+        // PageFilter does not guarantee that the number of results is <=
+        // pageSize, so this
+        // break is required.
+        if (numResults >= recordcount) {// if hit recordcount, bail out
+          break;
+        }
+      } // done with row
+    } catch (IOException e) {
+      if (debug) {
+        System.out.println("Error in getting/parsing scan result: " + e);
+      }
+      return Status.ERROR;
+    } finally {
+      if (scanner != null) {
+        scanner.close();
+      }
     }
 
-    /**
-     * Insert a record in the database. Any field/value pairs in the specified values HashMap will be written into the record with the specified
-     * record key.
-     *
-     * @param table The name of the table
-     * @param key The record key of the record to insert.
-     * @param values A HashMap of field/value pairs to insert in the record
-     * @return Zero on success, a non-zero error code on error
-     */
-    @Override
-    public Status insert(String table, String key, HashMap<String,ByteIterator> values)
-    {
-        return update(table,key,values);
+    return Status.OK;
+  }
+
+  /**
+   * Update a record in the database. Any field/value pairs in the specified
+   * values HashMap will be written into the record with the specified record
+   * key, overwriting any existing values with the same field name.
+   *
+   * @param table
+   *          The name of the table
+   * @param key
+   *          The record key of the record to write
+   * @param values
+   *          A HashMap of field/value pairs to update in the record
+   * @return Zero on success, a non-zero error code on error
+   */
+  @Override
+  public Status update(String table, String key,
+      HashMap<String, ByteIterator> values) {
+    // if this is a "new" table, init HTable object. Else, use existing one
+    if (!tableName.equals(table)) {
+      currentTable = null;
+      try {
+        getHTable(table);
+        tableName = table;
+      } catch (IOException e) {
+        System.err.println("Error accessing HBase table: " + e);
+        return Status.ERROR;
+      }
     }
 
-    /**
-     * Delete a record from the database.
-     *
-     * @param table The name of the table
-     * @param key The record key of the record to delete.
-     * @return Zero on success, a non-zero error code on error
-     */
-    @Override
-    public Status delete(String table, String key)
-    {
-        //if this is a "new" table, init HTable object.  Else, use existing one
-        if (!_tableName.equals(table)) {
-            _table = null;
-            try
-            {
-                getHTable(table);
-                _tableName = table;
-            }
-            catch (IOException e)
-            {
-                System.err.println("Error accessing HBase table: "+e);
-                return Status.ERROR;
-            }
-        }
+    if (debug) {
+      System.out.println("Setting up put for key: " + key);
+    }
+    Put p = new Put(Bytes.toBytes(key));
+    p.setDurability(durability);
+    for (Map.Entry<String, ByteIterator> entry : values.entrySet()) {
+      byte[] value = entry.getValue().toArray();
+      if (debug) {
+        System.out.println("Adding field/value " + entry.getKey() + "/"
+            + Bytes.toStringBinary(value) + " to put request");
+      }
+      p.addColumn(columnFamilyBytes, Bytes.toBytes(entry.getKey()), value);
+    }
 
-        if (_debug) {
-            System.out.println("Doing delete for key: "+key);
-        }
+    try {
+      if (clientSideBuffering) {
+        Preconditions.checkNotNull(bufferedMutator);
+        bufferedMutator.mutate(p);
+      } else {
+        currentTable.put(p);
+      }
+    } catch (IOException e) {
+      if (debug) {
+        System.err.println("Error doing put: " + e);
+      }
+      return Status.ERROR;
+    } catch (ConcurrentModificationException e) {
+      // do nothing for now...hope this is rare
+      return Status.ERROR;
+    }
 
-        final Delete d = new Delete(Bytes.toBytes(key));
-        d.setDurability(_durability);
-        try
-        {
-            if (_clientSideBuffering) {
-                Preconditions.checkNotNull(_bufferedMutator);
-                _bufferedMutator.mutate(d);
-            } else {
-                _table.delete(d);
-            }
-        }
-        catch (IOException e)
-        {
-            if (_debug) {
-                System.err.println("Error doing delete: "+e);
-            }
-            return Status.ERROR;
-        }
+    return Status.OK;
+  }
+
+  /**
+   * Insert a record in the database. Any field/value pairs in the specified
+   * values HashMap will be written into the record with the specified record
+   * key.
+   *
+   * @param table
+   *          The name of the table
+   * @param key
+   *          The record key of the record to insert.
+   * @param values
+   *          A HashMap of field/value pairs to insert in the record
+   * @return Zero on success, a non-zero error code on error
+   */
+  @Override
+  public Status insert(String table, String key,
+      HashMap<String, ByteIterator> values) {
+    return update(table, key, values);
+  }
+
+  /**
+   * Delete a record from the database.
+   *
+   * @param table
+   *          The name of the table
+   * @param key
+   *          The record key of the record to delete.
+   * @return Zero on success, a non-zero error code on error
+   */
+  @Override
+  public Status delete(String table, String key) {
+    // if this is a "new" table, init HTable object. Else, use existing one
+    if (!tableName.equals(table)) {
+      currentTable = null;
+      try {
+        getHTable(table);
+        tableName = table;
+      } catch (IOException e) {
+        System.err.println("Error accessing HBase table: " + e);
+        return Status.ERROR;
+      }
+    }
 
-        return Status.OK;
+    if (debug) {
+      System.out.println("Doing delete for key: " + key);
     }
 
-    @VisibleForTesting
-    void setConfiguration(final Configuration config) {
-        this.config = config;
+    final Delete d = new Delete(Bytes.toBytes(key));
+    d.setDurability(durability);
+    try {
+      if (clientSideBuffering) {
+        Preconditions.checkNotNull(bufferedMutator);
+        bufferedMutator.mutate(d);
+      } else {
+        currentTable.delete(d);
+      }
+    } catch (IOException e) {
+      if (debug) {
+        System.err.println("Error doing delete: " + e);
+      }
+      return Status.ERROR;
     }
+
+    return Status.OK;
+  }
+
+  @VisibleForTesting
+  void setConfiguration(final Configuration newConfig) {
+    this.config = newConfig;
+  }
 }
 
-/* For customized vim control
- * set autoindent
- * set si
- * set shiftwidth=4
+/*
+ * For customized vim control set autoindent set si set shiftwidth=4
  */
-
diff --git a/hbase10/src/main/java/com/yahoo/ycsb/db/package-info.java b/hbase10/src/main/java/com/yahoo/ycsb/db/package-info.java
new file mode 100644
index 00000000..2b12ae41
--- /dev/null
+++ b/hbase10/src/main/java/com/yahoo/ycsb/db/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2014, Yahoo!, Inc. All rights reserved.
+ *
+ * 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. See accompanying
+ * LICENSE file.
+ */
+
+/**
+ * The YCSB binding for <a href="https://hbase.apache.org/">HBase</a> 
+ * using the HBase 1.0.0 API.
+ */
+package com.yahoo.ycsb.db;
+
-- 
GitLab