Package dovetaildb.dbservice

Source Code of dovetaildb.dbservice.BagIndexBridge

package dovetaildb.dbservice;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import dovetaildb.apiservice.ApiBuffer;
import dovetaildb.bagindex.BagIndex;
import dovetaildb.bagindex.BagIndexUtil;
import dovetaildb.bagindex.EditRec;
import dovetaildb.bytes.ArrayBytes;
import dovetaildb.bytes.Bytes;
import dovetaildb.bytes.CompoundBytes;
import dovetaildb.iter.EmptyIter;
import dovetaildb.iter.Iter;
import dovetaildb.iter.IterUtil;
import dovetaildb.iter.ScannerIter;
import dovetaildb.querynode.OrderedOrQueryNode;
import dovetaildb.querynode.QueryNode;
import dovetaildb.querynode.QueryNodeTemplate;
import dovetaildb.querynode.QueryNode.NextStatus;
import dovetaildb.scan.Scanner;
import dovetaildb.util.Pair;
import dovetaildb.util.Util;

public class BagIndexBridge implements DbService {

  ConcurrentHashMap<String,BagEntry> bagIndexes =
    new ConcurrentHashMap<String,BagEntry>();
 
  TransactionMapper txnMapper = null;
  public TransactionMapper getTxnMapper() { return txnMapper; }
  public void setTxnMapper(TransactionMapper txnMapper) { this.txnMapper = txnMapper; }

  private BagEntryFactory bagEntryFactory;
  public BagEntryFactory getBagEntryFactory() {
    return bagEntryFactory;
  }
  public void setBagIndexFactory(BagEntryFactory bagEntryFactory) {
    this.bagEntryFactory = bagEntryFactory;
  }
 
  public BagEntry getBagEntry(String bag) {
    return bagIndexes.get(bag);
  }
 
  public void setBagEntry(String bag, BagEntry bagEntry) {
    bagIndexes.put(bag, bagEntry);
  }
 
  public long capacity() {
    return 500;
  }
 
//  protected byte[][] encodeEntry(Map<String,Object> entry, TermEncoder encoder) {
//    byte[][] terms = new byte[entry.size()][];
//    int i = 0;
//    for(Map.Entry<String, Object> e : entry.entrySet()) {
//      terms[i++] = TermEncoderUtil.encodeWholeTerm(encoder, e.getKey(), e.getValue());
//    }
//    return terms;
//  }

  /*
  protected long commitBag(BufferedData buffer, BagIndex bagIndex, TermEncoder encoder, long revNum) {
    ArrayList<Pair<byte[][],byte[][]>> inserts = buffer.entries.dumpRecords();
   
//    ArrayList<Pair<byte[][],byte[][]>> inserts = new ArrayList<Pair<byte[][],byte[][]>>();
//    for(Map<String,Object> entry : buffer.getEntries().values()) {
//      inserts.add(new Pair<byte[][],byte[][]>(EMPTY_BYTES_ARRAY, encodeEntry(entry, encoder)));
//    }
//   
    HashSet<String> deletions = buffer.getDeletions();
   
    HashSet<String> deletionStrings = new HashSet<String>();
    byte[][] idTerms = new byte[deletionStrings.size()][];
    int i=0;
    for(String idString : deletionStrings) {
      idTerms[i++] = TermEncoderUtil.encodeWholeTerm(encoder, "id", idString);
    }
    long[] deletions = BagIndexUtil.getDocidsForIdTerms(idTerms, bagIndex, revNum);
    long commitRevNum = bagIndex.commitNewRev(deletions, inserts);
    return commitRevNum;
  }
  */

  static final ArrayBytes ID_BYTES;
  static final int NUM_ID_BYTES;
  static {
    try {
      ID_BYTES = new ArrayBytes("{id:".getBytes("utf-8"));
      NUM_ID_BYTES = ID_BYTES.getLength();
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
  }
 
  private ArrayList<EditRec> encodeBuffer(String bagName, long revNum, ApiBuffer value) {
    ArrayList<EditRec> edits = new ArrayList<EditRec>();

    // fashion directly and make a nodeiterator !!!
    BagEntry bagRec = bagIndexes.get(bagName);
    BagIndex index = bagRec.bagIndex;
    if (revNum == -1) revNum = index.getCurrentRevNum();

    // TODO: more efficient; BagIndex needs a "get multi"
    QueryNode data = index.getRange(ArrayBytes.EMPTY_BYTES, null, null, false, false, revNum);
    ArrayList<QueryNode> clauses = new ArrayList<QueryNode>(value.getDeletions().size()+value.getEntries().size());
   
    for(String key : value.getDeletions()) {
      QueryNode q = index.getTerm(new CompoundBytes(ID_BYTES, new ArrayBytes(Util.decodeString(key))), revNum);
      if (q == null) throw new RuntimeException("Object not found; id=\""+key+"\"");
      clauses.add(q);
    }
    if (clauses.size() > 0) {
      QueryNode idQuery = new OrderedOrQueryNode(clauses, null, null, null, false, false);
      do {
        long docId = idQuery.doc();
        data.skipTo(docId);
        do {
          edits.add(new EditRec(docId, data.term(), true));
        } while(data.nextTerm() == NextStatus.NEXT_TERM);
      } while(idQuery.next());
    }
   
    long insId = -1;
    for(Map.Entry<String,Object> entry : value.getEntries().entrySet()) {
      String key = entry.getKey();
      QueryNode q = index.getTerm(new CompoundBytes(ID_BYTES, new ArrayBytes(Util.decodeString(key))), revNum);
      if (q != null) {
        clauses.add(q);
      } else {
        long docId = insId--;
        DbServiceUtil.sencodeMulti(ArrayBytes.EMPTY_BYTES, entry.getValue(), edits, docId, false);
      }
    }
    if (clauses.size() > 0) {
      QueryNode idQuery = new OrderedOrQueryNode(clauses, null, null, null, false, false);
      Map<String, Object> entries = value.getEntries();
      do {
        long docId = idQuery.doc();
        Bytes idTerm = idQuery.term();
        byte[] idBytes = idTerm.subBytes(NUM_ID_BYTES, idTerm.getLength()-NUM_ID_BYTES).getBytes();
        Object val = entries.get(Util.encodeBytes(idBytes));
        DbServiceUtil.sencodeMulti(ArrayBytes.EMPTY_BYTES, val, edits, docId, false);
      } while(idQuery.next());
    }
    return edits;
  }
 
  public void commit(long fromTxnId, long commitTxnId, Map<String, ApiBuffer> batch) throws CommitFailedException {
    HashMap<String,Long> bagRevs = new HashMap<String,Long>();
    for(Map.Entry<String,ApiBuffer> entry : batch.entrySet()) {
      String bag = entry.getKey();
      BagEntry rec = bagIndexes.get(bag);
      if (rec == null) {
        rec = bagEntryFactory.makeBagEntry(bag);
        rec.initialTxn = commitTxnId;
        bagIndexes.put(bag, rec);
      }
      try {
        long revNum = txnMapper.getRevForTxn(bag, fromTxnId);
        ArrayList<EditRec> bufferedData = encodeBuffer(bag, revNum, entry.getValue())
        long commitRevNum = rec.bagIndex.commitNewRev(bufferedData);
        bagRevs.put(bag, commitRevNum);
      } catch (TxnNotFoundException e) {
        throw new RuntimeException(e);
      }
    }
    txnMapper.addRevsForTxn(commitTxnId, bagRevs);
  }
 
  public void drop() {
    for(String bag : bagIndexes.keySet()) {
      dropBag(bag);
    }
  }
 
  public void dropBag(String bagName) {
    BagEntry entry = bagIndexes.get(bagName);
    entry.bagIndex.close();
    bagIndexes.put(bagName, null);
  }
 
  public Collection<String> getBags(long txnId) {
    ArrayList<String> bags = new ArrayList<String>();
    for(String bag : bagIndexes.keySet()) {
      try {
        long rev = txnMapper.getRevForTxn(bag, txnId);
        if (rev >= 1) bags.add(bag);
      } catch (TxnNotFoundException e) {
        return null;
      }
    }
    return bags;
  }
 
  public void initialize() {
  }

  @Override
  public Iter query(String bag, long txnId, Object query, Map<String, Object> options) {
    BagEntry rec = bagIndexes.get(bag);
    if (rec == null) return EmptyIter.EMPTY_ITER;
    BagIndex index = rec.bagIndex;
    try {
      long revNum = txnMapper.getRevForTxn(bag, txnId);
      if (revNum == -1) return EmptyIter.EMPTY_ITER;
      QueryNodeTemplate templ = DbServiceUtil.applyPatternToBagIndex(query, index, revNum);
      return QueryNodeIter.make(templ);
    } catch (TxnNotFoundException e) {
      throw new RuntimeException(e);
    }
  }

  public void rollback(long commitId) {
  }
 
  public ApiBuffer createBufferedData(String bagName) {
    return new ApiBuffer();
   
  }
}
TOP

Related Classes of dovetaildb.dbservice.BagIndexBridge

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.