Package HBaseIA.TwitBase.hbase

Source Code of HBaseIA.TwitBase.hbase.RelationsDAO$Relation

package HBaseIA.TwitBase.hbase;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.HTablePool;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.coprocessor.Batch;
import org.apache.hadoop.hbase.util.Bytes;

import utils.Md5Utils;
import HBaseIA.TwitBase.coprocessors.RelationCountProtocol;

public class RelationsDAO {

  // md5(id_from)md5(id_to) -> 'f':id_to=name_to
  // md5(id_from)md5(id_to) -> 'f':'to'=id_to, 'f':'from'=id_from

  public static final byte[] FOLLOWS_TABLE_NAME = Bytes.toBytes("follows");
  public static final byte[] FOLLOWED_TABLE_NAME = Bytes.toBytes("followedBy");
  public static final byte[] RELATION_FAM = Bytes.toBytes("f");
  public static final byte[] FROM = Bytes.toBytes("from");
  public static final byte[] TO = Bytes.toBytes("to");

  private static final int KEY_WIDTH = 2 * Md5Utils.MD5_LENGTH;

  private HTablePool pool;

  public RelationsDAO(HTablePool pool) {
    this.pool = pool;
  }

  public static byte[] mkRowKey(String a) {
    byte[] ahash = Md5Utils.md5sum(a);
    byte[] rowkey = new byte[KEY_WIDTH];

    Bytes.putBytes(rowkey, 0, ahash, 0, ahash.length);
    return rowkey;
  }

  public static byte[] mkRowKey(String a, String b) {
    byte[] ahash = Md5Utils.md5sum(a);
    byte[] bhash = Md5Utils.md5sum(b);
    byte[] rowkey = new byte[KEY_WIDTH];

    int offset = 0;
    offset = Bytes.putBytes(rowkey, offset, ahash, 0, ahash.length);
    Bytes.putBytes(rowkey, offset, bhash, 0, bhash.length);
    return rowkey;
  }

  public static byte[][] splitRowkey(byte[] rowkey) {
    byte[][] result = new byte[2][];

    result[0] = Arrays.copyOfRange(rowkey, 0, Md5Utils.MD5_LENGTH);
    result[1] = Arrays.copyOfRange(rowkey, Md5Utils.MD5_LENGTH, KEY_WIDTH);
    return result;
  }

  public void addFollows(String fromId, String toId) throws IOException {
    addRelation(FOLLOWS_TABLE_NAME, fromId, toId);
  }

  public void addFollowedBy(String fromId, String toId) throws IOException {
    addRelation(FOLLOWED_TABLE_NAME, fromId, toId);
  }

  public void addRelation(byte[] table, String fromId, String toId) throws IOException {

    HTableInterface t = pool.getTable(table);

    Put p = new Put(mkRowKey(fromId, toId));
    p.add(RELATION_FAM, FROM, Bytes.toBytes(fromId));
    p.add(RELATION_FAM, TO, Bytes.toBytes(toId));
    t.put(p);

    t.close();
  }

  public List<HBaseIA.TwitBase.model.Relation> listFollows(String fromId) throws IOException {
    return listRelations(FOLLOWS_TABLE_NAME, fromId);
  }

  public List<HBaseIA.TwitBase.model.Relation> listFollowedBy(String fromId) throws IOException {
    return listRelations(FOLLOWED_TABLE_NAME, fromId);
  }

  public List<HBaseIA.TwitBase.model.Relation> listRelations(byte[] table, String fromId) throws IOException {

    HTableInterface t = pool.getTable(table);
    String rel = (Bytes.equals(table, FOLLOWS_TABLE_NAME)) ? "->" : "<-";

    byte[] startKey = mkRowKey(fromId);
    byte[] endKey = Arrays.copyOf(startKey, startKey.length);
    endKey[Md5Utils.MD5_LENGTH-1]++;
    Scan scan = new Scan(startKey, endKey);
    scan.addColumn(RELATION_FAM, TO);
    scan.setMaxVersions(1);

    ResultScanner results = t.getScanner(scan);
    List<HBaseIA.TwitBase.model.Relation> ret
      = new ArrayList<HBaseIA.TwitBase.model.Relation>();
    for (Result r : results) {
      KeyValue kv = r.getColumnLatest(RELATION_FAM, TO);
      String toId = Bytes.toString(kv.getValue());
      ret.add(new Relation(rel, fromId, toId));
    }

    t.close();
    return ret;
  }

  @SuppressWarnings("unused")
  public long followedByCountScan (String user) throws IOException {
    HTableInterface followed = pool.getTable(FOLLOWED_TABLE_NAME);

    final byte[] startKey = Md5Utils.md5sum(user);
    final byte[] endKey = Arrays.copyOf(startKey, startKey.length);
    endKey[endKey.length-1]++;
    Scan scan = new Scan(startKey, endKey);
    scan.setMaxVersions(1);

    long sum = 0;
    ResultScanner rs = followed.getScanner(scan);
    for(Result r : rs) {
      sum++;
    }
    return sum;
  }

  public long followedByCount (final String userId) throws Throwable {
    HTableInterface followed = pool.getTable(FOLLOWED_TABLE_NAME);

    final byte[] startKey = Md5Utils.md5sum(userId);
    final byte[] endKey = Arrays.copyOf(startKey, startKey.length);
    endKey[endKey.length-1]++;

    Batch.Call<RelationCountProtocol, Long> callable =
      new Batch.Call<RelationCountProtocol, Long>() {
        @Override
        public Long call(RelationCountProtocol instance)
            throws IOException {
          return instance.followedByCount(userId);
        }
    };

    Map<byte[], Long> results =
      followed.coprocessorExec(
        RelationCountProtocol.class,
        startKey,
        endKey,
        callable);

    long sum = 0;
    for(Map.Entry<byte[], Long> e : results.entrySet()) {
      sum += e.getValue().longValue();
    }
    return sum;
  }

  private static class Relation extends HBaseIA.TwitBase.model.Relation {

    private Relation(String relation, String from, String to) {
      this.relation = relation;
      this.from = from;
      this.to = to;
    }
  }
}
TOP

Related Classes of HBaseIA.TwitBase.hbase.RelationsDAO$Relation

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.