Package avrobase.redis

Source Code of avrobase.redis.RAB

package avrobase.redis;

import avrobase.AvroBaseException;
import avrobase.AvroBaseImpl;
import avrobase.AvroFormat;
import avrobase.Row;
import com.google.common.base.Supplier;
import org.apache.avro.Schema;
import org.apache.avro.specific.SpecificRecord;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisException;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.TransactionBlock;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

import java.util.List;
import java.util.concurrent.TimeoutException;

/**
* AvroBase on top of Redis
* <p/>
* User: sam
* Date: Oct 3, 2010
* Time: 11:32:10 AM
*/
@SuppressWarnings({"unchecked"})
public class RAB<T extends SpecificRecord> extends AvroBaseImpl<T, String> {

  private JedisPool pool;
  private int db;
  private Supplier<String> kg;

  private static final String d = "_d";
  private static final String s = "_s";
  private static final String v = "_v";
  private static final String z = "_z";

  public RAB(JedisPool pool, int db, Supplier<String> kg, Schema actualSchema) {
    super(actualSchema, AvroFormat.JSON);
    this.pool = pool;
    this.db = db;
    this.kg = kg;
  }

  @Override
  public Row<T, String> get(final String row) throws AvroBaseException {
    try {
      boolean returned = false;
      final Jedis j = pool.getResource();
      try {
        j.select(db);
        List<Object> results;
        do {
          results = j.multi(new TransactionBlock() {
            @Override
            public void execute() throws JedisException {
              mget(row + s, row + v, row + d);
            }
          });
        } while (results == null);
        if (results.size() != 1 || (results = (List<Object>) results.get(0)).size() != 3) {
          throw new AvroBaseException("Incorrect number of results from redis transaction: " + results);
        }
        String schemaId = (String) results.get(0);
        String versionStr = (String) results.get(1);
        String data = (String) results.get(2);
        if (versionStr == null || schemaId == null || data == null) {
          return null;
        }
        Schema schema = schemaCache.get(schemaId);
        if (schema == null) {
          schema = loadSchema(j.get(schemaId + z).getBytes(), schemaId);
        }
        return new Row<T, String>(readValue(data.getBytes(), schema, format), row, Long.parseLong(versionStr));
      } catch (Exception e) {
        pool.returnBrokenResource(j);
        returned = true;
        throw new AvroBaseException(e);
      } finally {
        if (!returned) pool.returnResource(j);
      }
    } catch (TimeoutException e) {
      throw new AvroBaseException("Timed out", e);
    }
  }

  @Override
  public String create(T value) throws AvroBaseException {
    String row;
    do {
      row = kg.get();
    } while(!put(row, value, 0));
    return row;
  }

  @Override
  public void put(final String row, final T value) throws AvroBaseException {
    try {
      boolean returned = false;
      Jedis j = pool.getResource();
      try {
        j.select(db);
        Schema schema = value.getSchema();
        String schemaKey = hashCache.get(schema);
        if (schemaKey == null) {
          final String doc = schema.toString();
          schemaKey = createSchemaKey(schema, doc);
          j.set(schemaKey + z, doc);
        }
        final String finalSchemaKey = schemaKey;
        List<Object> results;
        do {
          results = j.multi(new TransactionBlock() {
            @Override
            public void execute() throws JedisException {
              incr(row + v);
              mset(row + s, finalSchemaKey, row + d, new String(serialize(value), UTF8));
            }
          });
        } while (results == null);
      } catch (Exception e) {
        pool.returnBrokenResource(j);
        returned = true;
        throw new AvroBaseException(e);
      } finally {
        if (!returned) pool.returnResource(j);
      }
    } catch (TimeoutException e) {
      throw new AvroBaseException("Timed out", e);
    }
  }

  @Override
  public boolean put(final String row, final T value, final long version) throws AvroBaseException {
    try {
      boolean returned = false;
      final Jedis j = pool.getResource();
      try {
        j.select(db);
        Schema schema = value.getSchema();
        String schemaKey = hashCache.get(schema);
        if (schemaKey == null) {
          final String doc = schema.toString();
          schemaKey = createSchemaKey(schema, doc);
          j.set(schemaKey + z, doc);
        }
        String watch = j.watch(row + v);
        if (!watch.equals("OK")) {
          return false;
        }
        String versionStr = j.get(row + v);
        if ((versionStr == null && version != 0) || // row missing but version set
            (versionStr != null && version == 0) || // row exists but insert requested
            (versionStr != null && !versionStr.equals(String.valueOf(version))) // version in db doesn't match
            ) {
          return false;
        }
        final String finalSchemaKey = schemaKey;
        List<Object> results = j.multi(new TransactionBlock() {
          @Override
          public void execute() throws JedisException {
            mset(row + v, String.valueOf(version + 1), row + s, finalSchemaKey, row + d, new String(serialize(value), UTF8));
          }
        });
        return results != null;
      } catch (Exception e) {
        pool.returnBrokenResource(j);
        returned = true;
        throw new AvroBaseException(e);
      } finally {
        if (!returned) pool.returnResource(j);
      }
    } catch (TimeoutException e) {
      throw new AvroBaseException("Timed out", e);
    }
  }

  @Override
  public void delete(final String row) throws AvroBaseException {
    try {
      boolean returned = false;
      Jedis j = pool.getResource();
      try {
        j.select(db);
        List<Object> results;
        do {
          results = j.multi(new TransactionBlock() {
            @Override
            public void execute() throws JedisException {
              del(row + v); // Delete the version first and it is deleted
              del(row + d);
              del(row + s);
            }
          });
        } while (results == null);
      } catch (Exception e) {
        pool.returnBrokenResource(j);
        returned = true;
        throw new AvroBaseException(e);
      } finally {
        if (!returned) pool.returnResource(j);
      }
    } catch (TimeoutException e) {
      throw new AvroBaseException("Timed out", e);
    }
  }

  @Override
  public Iterable<Row<T, String>> scan(String startRow, String stopRow) throws AvroBaseException {
    throw new NotImplementedException();
  }
}
TOP

Related Classes of avrobase.redis.RAB

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.