Package com.yahoo.ycsb.db

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

package com.yahoo.ycsb.db;

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

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;

import com.yahoo.mapkeeper.BinaryResponse;
import com.yahoo.mapkeeper.MapKeeper;
import com.yahoo.mapkeeper.Record;
import com.yahoo.mapkeeper.RecordListResponse;
import com.yahoo.mapkeeper.ResponseCode;
import com.yahoo.mapkeeper.ScanOrder;
import com.yahoo.ycsb.ByteIterator;
import com.yahoo.ycsb.DB;
import com.yahoo.ycsb.StringByteIterator;
import com.yahoo.ycsb.workloads.CoreWorkload;

public class MapKeeperClient extends DB {
    private static final String HOST = "mapkeeper.host";
    private static final String HOST_DEFAULT = "localhost";
    private static final String PORT = "mapkeeper.port";
    private static final String PORT_DEFAULT = "9090";
    MapKeeper.Client c;
    boolean writeallfields;
    static boolean initteddb = false;
    private synchronized static void initDB(Properties p, MapKeeper.Client c) throws TException {
        if(!initteddb) {
            initteddb = true;
            c.addMap(p.getProperty(CoreWorkload.TABLENAME_PROPERTY, CoreWorkload.TABLENAME_PROPERTY_DEFAULT));
        }
    }

    public void init() {
        String host = getProperties().getProperty(HOST, HOST_DEFAULT);
        int port = Integer.parseInt(getProperties().getProperty(PORT, PORT_DEFAULT));
        TTransport tr = new TFramedTransport(new TSocket(host, port));
        TProtocol proto = new TBinaryProtocol(tr);
        c = new MapKeeper.Client(proto);
        try {
            tr.open();
            initDB(getProperties(), c);
        } catch(TException e) {
            throw new RuntimeException(e);
        }
        writeallfields = Boolean.parseBoolean(getProperties().getProperty(CoreWorkload.WRITE_ALL_FIELDS_PROPERTY,
                    CoreWorkload.WRITE_ALL_FIELDS_PROPERTY_DEFAULT));
    }

    ByteBuffer encode(HashMap<String, ByteIterator> values) {
        int len = 0;
        for(String k : values.keySet()) {
            len += (k.length() + 1 + values.get(k).bytesLeft() + 1);
        }
        byte[] array = new byte[len];
        int i = 0;
        for(String k : values.keySet()) {
            for(int j = 0; j < k.length(); j++) {
                array[i] = (byte)k.charAt(j);
                i++;
            }
            array[i] = '\t'; // XXX would like to use sane delimiter (null, 254, 255, ...) but java makes this nearly impossible
            i++;
            ByteIterator v = values.get(k);
            i = v.nextBuf(array, i);
            array[i] = '\t';
            i++;
        }
        array[array.length-1] = 0;
        ByteBuffer buf = ByteBuffer.wrap(array);
        buf.rewind();
        return buf;
    }
    void decode(Set<String> fields, String tups, HashMap<String, ByteIterator> tup) {
        String[] tok = tups.split("\\t");
        if(tok.length == 0) { throw new IllegalStateException("split returned empty array!"); }
        for(int i = 0; i < tok.length; i+=2) {
            if(fields == null || fields.contains(tok[i])) {
                if(tok.length < i+2) { throw new IllegalStateException("Couldn't parse tuple <" + tups + "> at index " + i); }
                if(tok[i] == null || tok[i+1] == null) throw new NullPointerException("Key is " + tok[i] + " val is + " + tok[i+1]);
                tup.put(tok[i], new StringByteIterator(tok[i+1]));
            }
        }
        if(tok.length == 0) {
            System.err.println("Empty tuple: " + tups);
        }
    }

    int ycsbThriftRet(BinaryResponse succ, ResponseCode zero, ResponseCode one) {
        return ycsbThriftRet(succ.responseCode, zero, one);
    }
    int ycsbThriftRet(ResponseCode rc, ResponseCode zero, ResponseCode one) {
        return
            rc == zero ? 0 :
            rc == one  ? 1 : 2;
    }
    ByteBuffer bufStr(String str) {
        ByteBuffer buf = ByteBuffer.wrap(str.getBytes());
        return buf;
    }
    String strResponse(BinaryResponse buf) {
        return new String(buf.value.array());
    }

    @Override
    public int read(String table, String key, Set<String> fields,
            HashMap<String, ByteIterator> result) {
        try {
            ByteBuffer buf = bufStr(key);

            BinaryResponse succ = c.get(table, buf);

            int ret = ycsbThriftRet(
                    succ,
                    ResponseCode.RecordExists,
                    ResponseCode.RecordNotFound);

            if(ret == 0) {
                decode(fields, strResponse(succ), result);
            }
            return ret;
        } catch(TException e) {
            e.printStackTrace();
            return 2;
        }
    }

    @Override
    public int scan(String table, String startkey, int recordcount,
            Set<String> fields, Vector<HashMap<String, ByteIterator>> result) {
        try {
            //XXX what to pass in for nulls / zeros?
            RecordListResponse res = c.scan(table, ScanOrder.Ascending, bufStr(startkey), true, null, false, recordcount, 0);
            int ret = ycsbThriftRet(res.responseCode, ResponseCode.Success, ResponseCode.ScanEnded);
            if(ret == 0) {
                for(Record r : res.records) {
                    HashMap<String, ByteIterator> tuple = new HashMap<String, ByteIterator>();
                    // Note: r.getKey() and r.getValue() call special helper methods that trim the buffer
                    // to an appropriate length, and memcpy it to a byte[].  Trying to manipulate the ByteBuffer
                    // directly leads to trouble.
                    tuple.put("key", new StringByteIterator(new String(r.getKey())));
                    decode(fields, new String(r.getValue())/*strBuf(r.bufferForValue())*/, tuple);
                    result.add(tuple);
                }
            }
            return ret;
        } catch(TException e) {
            e.printStackTrace();
            return 2;
        }
    }

    @Override
    public int update(String table, String key,
            HashMap<String, ByteIterator> values) {
        try {
            if(!writeallfields) {
                HashMap<String, ByteIterator> oldval = new HashMap<String, ByteIterator>();
                read(table, key, null, oldval);
                for(String k: values.keySet()) {
                    oldval.put(k, values.get(k));
                }
                values = oldval;
            }
            ResponseCode succ = c.update(table, bufStr(key), encode(values));
            return ycsbThriftRet(succ, ResponseCode.RecordExists, ResponseCode.RecordNotFound);
        } catch(TException e) {
            e.printStackTrace();
            return 2;
        }
    }

    @Override
    public int insert(String table, String key,
            HashMap<String, ByteIterator> values) {
        try {
            int ret = ycsbThriftRet(c.insert(table, bufStr(key), encode(values)), ResponseCode.Success, ResponseCode.RecordExists);
            return ret;
        } catch(TException e) {
            e.printStackTrace();
            return 2;
        }
    }

    @Override
    public int delete(String table, String key) {
        try {
            return ycsbThriftRet(c.remove(table, bufStr(key)), ResponseCode.Success, ResponseCode.RecordExists);
        } catch(TException e) {
            e.printStackTrace();
            return 2;
        }
    }
}
TOP

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

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.