Package com.yahoo.ycsb.db

Source Code of com.yahoo.ycsb.db.HypertableClient

/**
* 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.
*/

package com.yahoo.ycsb.db;


import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.apache.thrift.TException;
import org.hypertable.thrift.SerializedCellsFlag;
import org.hypertable.thrift.SerializedCellsWriter;
import org.hypertable.thrift.ThriftClient;
import org.hypertable.thriftgen.Cell;
import org.hypertable.thriftgen.ClientException;
import org.hypertable.thriftgen.Key;
import org.hypertable.thriftgen.KeyFlag;
import org.hypertable.thriftgen.RowInterval;
import org.hypertable.thriftgen.ScanSpec;
import org.hypertable.thrift.SerializedCellsReader;

import com.yahoo.ycsb.ByteArrayByteIterator;
import com.yahoo.ycsb.ByteIterator;
import com.yahoo.ycsb.DBException;

/**
* Hypertable client for YCSB framework
*/
public class HypertableClient extends com.yahoo.ycsb.DB
{
    private boolean _debug = false;
   
    private ThriftClient connection;
    private long ns;

    private String _columnFamily = "";

    public static final int OK = 0;
    public static final int SERVERERROR = -1;
   
    public static final String NAMESPACE = "/ycsb";
    public static final int THRIFTBROKER_PORT = 38080;

    //TODO: make dynamic
    public static final int BUFFER_SIZE = 4096;
   
    /**
     * 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 ( (getProperties().getProperty("debug") != null) &&
                (getProperties().getProperty("debug").equals("true")) )
        {
            _debug = true;
        }
       
        try {
            connection = ThriftClient.create("localhost", THRIFTBROKER_PORT);
           
            if (!connection.namespace_exists(NAMESPACE)) {
                connection.namespace_create(NAMESPACE);
            }   
            ns = connection.open_namespace(NAMESPACE);
        } catch (ClientException e) {
            throw new DBException("Could not open namespace", e);
        } catch (TException e) {
            throw new DBException("Could not open namespace", e);
        }
           
       
        _columnFamily = getProperties().getProperty("columnfamily");
        if (_columnFamily == null)
        {
            System.err.println("Error, must specify a " +
                "columnfamily for Hypertable table");
            throw new DBException("No columnfamily specified");
        }
    }

    /**
     * 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
    {
        try {
            connection.namespace_close(ns);
        } catch (ClientException e) {
            throw new DBException("Could not close namespace", e);
        } catch (TException e) {
            throw new DBException("Could not close namespace", e);
        }
    }
   
    /**
     * 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
     */
    @Override
    public int read(String table, String key, Set<String> fields,
                    HashMap<String, ByteIterator> result)
    {
        //SELECT _column_family:field[i]
        //  FROM table WHERE ROW=key MAX_VERSIONS 1;

        if (_debug) {
            System.out.println("Doing read from Hypertable columnfamily " +
                    _columnFamily);
            System.out.println("Doing read for key: " + key);
        }
       
        try {
            if (null != fields) {
                Vector<HashMap<String, ByteIterator>> resMap =
                        new Vector<HashMap<String, ByteIterator>>();
                if (0 != scan(table, key, 1, fields, resMap)) {
                    return SERVERERROR;
                }
                if (!resMap.isEmpty())
                    result.putAll(resMap.firstElement());
            } else {
                SerializedCellsReader reader = new SerializedCellsReader(null);
                reader.reset(connection.get_row_serialized(ns, table, key));
                while (reader.next()) {
                    result.put(new String(reader.get_column_qualifier()),
                            new ByteArrayByteIterator(reader.get_value()));
                }
            }
        } catch (ClientException e) {
            if (_debug) {
                System.err.println("Error doing read: " + e.message);
            }
            return SERVERERROR;
        } catch (TException e) {
            if (_debug)
                System.err.println("Error doing read");
            return SERVERERROR;
        }

        return 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 int scan(String table, String startkey, int recordcount,
                    Set<String> fields,
                    Vector<HashMap<String, ByteIterator>> result)
    {
        //SELECT _columnFamily:fields FROM table WHERE (ROW >= startkey)
        //    LIMIT recordcount MAX_VERSIONS 1;
       
        ScanSpec spec = new ScanSpec();
        RowInterval elem = new RowInterval();
        elem.setStart_inclusive(true);
        elem.setStart_row(startkey);
        spec.addToRow_intervals(elem);
        if (null != fields) {
            for (String field : fields) {
                spec.addToColumns(_columnFamily + ":" + field);
            }
        }
        spec.setVersions(1);
        spec.setRow_limit(recordcount);

        SerializedCellsReader reader = new SerializedCellsReader(null);

        try {
            long sc = connection.scanner_open(ns, table, spec);
                       
            String lastRow = null;
            boolean eos = false;
            while (!eos) {
                reader.reset(connection.scanner_get_cells_serialized(sc));
                while (reader.next()) {
                    String currentRow = new String(reader.get_row());
                    if (!currentRow.equals(lastRow)) {
                        result.add(new HashMap<String, ByteIterator>());
                        lastRow = currentRow;
                    }
                    result.lastElement().put(
                            new String(reader.get_column_qualifier()),
                            new ByteArrayByteIterator(reader.get_value()));
                }
                eos = reader.eos();
               

                if (_debug) {
                    System.out.println("Number of rows retrieved so far: " +
                                        result.size());
                }
            }
            connection.scanner_close(sc);
        } catch (ClientException e) {
            if (_debug) {
                System.err.println("Error doing scan: " + e.message);
            }
            return SERVERERROR;
        } catch (TException e) {
            if (_debug)
                System.err.println("Error doing scan");
            return SERVERERROR;           
        }
       
        return 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 int update(String table, String key,
            HashMap<String, ByteIterator> values)
    {
        return insert(table, key, values);
    }

    /**
     * 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 int insert(String table, String key,
            HashMap<String, ByteIterator> values)
    {
        //INSERT INTO table VALUES
        //  (key, _column_family:entry,getKey(), entry.getValue()), (...);

        if (_debug) {
            System.out.println("Setting up put for key: " + key);
        }
       
        try {
            long mutator = connection.mutator_open(ns, table, 0, 0);
            SerializedCellsWriter writer =
                    new SerializedCellsWriter(BUFFER_SIZE*values.size(), true);
            for (Map.Entry<String, ByteIterator> entry : values.entrySet()) {
                writer.add(key, _columnFamily, entry.getKey(),
                        SerializedCellsFlag.AUTO_ASSIGN,
                        ByteBuffer.wrap(entry.getValue().toArray()));           
            }
            connection.mutator_set_cells_serialized(mutator,
                    writer.buffer(), true);
            connection.mutator_close(mutator);
        } catch (ClientException e) {
            if (_debug) {
                System.err.println("Error doing set: " + e.message);
            }
            return SERVERERROR;
        } catch (TException e) {
            if (_debug)
                System.err.println("Error doing set");
            return SERVERERROR;
        }
       
        return OK;
    }

    /**
     * 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 int delete(String table, String key)
    {
        //DELETE * FROM table WHERE ROW=key;
       
        if (_debug) {
            System.out.println("Doing delete for key: "+key);
        }
       
        Cell entry = new Cell();
        entry.key = new Key();
        entry.key.row = key;
        entry.key.flag = KeyFlag.DELETE_ROW;
       
        try {
            connection.set_cell(ns, table, entry);
        } catch (ClientException e) {
            if (_debug) {
                System.err.println("Error doing delete: " + e.message);
            }
            return SERVERERROR;           
        } catch (TException e) {
            if (_debug)
                System.err.println("Error doing delete");
            return SERVERERROR;
        }
     
        return OK;
    }
}

TOP

Related Classes of com.yahoo.ycsb.db.HypertableClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.