Package org.hyperdex.ycsb

Source Code of org.hyperdex.ycsb.HyperDex

/**
* Copyright (c) 2011-2013, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of HyperDex nor the names of its contributors may be
*       used to endorse or promote products derived from this software without
*       specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

/* Descriptions borrowed from YCSB base. */

package org.hyperdex.ycsb;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.AbstractMap;
import java.util.regex.*;

import com.yahoo.ycsb.DB;
import com.yahoo.ycsb.DBException;
import com.yahoo.ycsb.ByteIterator;
import com.yahoo.ycsb.StringByteIterator;

import org.hyperdex.client.ByteString;
import org.hyperdex.client.Client;
import org.hyperdex.client.HyperDexClientException;
import org.hyperdex.client.Iterator;

public class HyperDex extends DB
{
    private Client m_client;
    private Pattern m_pat;
    private Matcher m_mat;
    private boolean m_scannable;
    private int m_retries;

    /**
     * Initialize any state for this DB.
     * Called once per DB instance; there is one DB instance per client thread.
     */
    public void init() throws DBException
    {
        String host = getProperties().getProperty("hyperdex.host", "127.0.0.1");
        Integer port = Integer.parseInt(getProperties().getProperty("hyperdex.port", "1982"));
        m_client = new Client(host, port);
        m_pat = Pattern.compile("([a-zA-Z]*)([0-9]*)");
        m_mat = m_pat.matcher("user1");
        m_scannable = getProperties().getProperty("hyperdex.scannable", "false").equals("true");
        m_retries = 10;
    }

    /**
     * Cleanup any state for this DB.
     * Called once per DB instance; there is one DB instance per client thread.
     */
    public void cleanup() throws DBException
    {
    }

    /**
     * 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 or "not found".
     */
    public int read(String table, String key, Set<String> fields, HashMap<String,ByteIterator> result)
    {
        while (true)
        {
            Map map = new HashMap<String,Object>();

            try
            {
                map = m_client.get(table, key);
            }
            catch(HyperDexClientException e)
            {
                if (e.status() == 8517)
                {
                    continue;
                }

                return 1;
            }
            catch(Exception e)
            {
                return 1;
            }

            convert_to_java(fields, map, result);
            return 0;
        }
    }

    /**
     * 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.  See this class's description for a discussion of error codes.
     */
    public int scan(String table, String startkey, int recordcount, Set<String> fields, Vector<HashMap<String,ByteIterator>> result)
    {
        while (true)
        {
            // XXX I'm going to be lazy and not support "fields" for now.  Patches
            // welcome.

            if (!m_scannable)
            {
                return 1;
            }

            m_mat.reset(startkey);

            if (!m_mat.matches())
            {
                return 2;
            }

            long base = Long.parseLong(m_mat.group(2));
            long lower = base << 32;
            long upper = (base + recordcount) << 32;

            HashMap<String,Object> values = new HashMap<String,Object>();
            AbstractMap.SimpleEntry<Long,Long> range
                = new AbstractMap.SimpleEntry<Long,Long>(lower,upper);
            values.put("recno", range);

            try
            {
                Iterator s = m_client.search(table, values);

                while (s.hasNext())
                {
                    s.next();
                }

                return 0;
            }
            catch(HyperDexClientException e)
            {
                if (e.status() == 8517)
                {
                    continue;
                }

                return 1;
            }
            catch(Exception e)
            {
                return 3;
            }
        }
    }

    /**
     * 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.  See this class's description for a discussion of error codes.
     */
    public int update(String table, String key, HashMap<String,ByteIterator> _values)
    {
        while (true)
        {
            HashMap<String,Object> values = new HashMap<String,Object>();

            for (Map.Entry<String, ByteIterator> entry : _values.entrySet())
            {
                values.put(entry.getKey(), new ByteString(entry.getValue().toArray()));
            }

            if (m_scannable)
            {
                m_mat.reset(key);

                if (!m_mat.matches())
                {
                    return -1;
                }

                long num = Long.parseLong(m_mat.group(2));
                values.put("recno", new Long(num << 32));
            }

            try
            {
                m_client.put(table, key, values);
                return 0;
            }
            catch(HyperDexClientException e)
            {
                if (e.status() == 8517)
                {
                    continue;
                }

                return 1;
            }
            catch(Exception e)
            {
                System.err.println(e.toString());
                return 1;
            }
        }
    }

    /**
     * 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.  See this class's description for a discussion of error codes.
     */
    public int 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.  See this class's description for a discussion of error codes.
     */
    public int delete(String table, String key)
    {
        while (true)
        {
            try
            {
                m_client.del(table, key);
                return 0;
            }
            catch(HyperDexClientException e)
            {
                if (e.status() == 8517)
                {
                    continue;
                }

                return 1;
            }
            catch(Exception e)
            {
                return 1;
            }
        }
    }

    private void convert_to_java(Set<String> fields, Map interres, HashMap<String,ByteIterator> result)
    {
        if (fields == null)
        {
            return;
        }

        for (String key : fields)
        {
            // Q: under which condition, interres.containsKey(key) is false?
            if (interres.containsKey(key))
            {
                result.put(key, new StringByteIterator(interres.get(key).toString()));
            }
        }
    }
}
TOP

Related Classes of org.hyperdex.ycsb.HyperDex

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.