Package dovetaildb.dbservice

Source Code of dovetaildb.dbservice.FsTransactionMapper

package dovetaildb.dbservice;

import java.io.File;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Map;

import dovetaildb.bagindex.EditRec;
import dovetaildb.bagindex.FsBlueSteelBagIndex;
import dovetaildb.bagindex.Range;
import dovetaildb.bytes.ArrayBytes;
import dovetaildb.bytes.Bytes;
import dovetaildb.bytes.CompoundBytes;
import dovetaildb.querynode.QueryNode;
import dovetaildb.querynode.QueryNode.NextStatus;
import dovetaildb.util.Util;

public class FsTransactionMapper implements TransactionMapper {

  private static final long serialVersionUID = -683617156786989352L;
 
  protected FsBlueSteelBagIndex map;
  transient protected long headTxn = -1;
  transient protected boolean nextReserved = false;

 
  private void readObject(ObjectInputStream in) {
    try {
      in.defaultReadObject();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    // figure out headTxn
    long revNum = map.getCurrentRevNum();
    QueryNode query = map.getRange(Range.OPEN_RANGE, revNum);
    if (query == null) {
      headTxn = -1;
    } else {
      long docId = query.doc();
      do {
        if (!query.positionSet(docId, ArrayBytes.EMPTY_BYTES)) {
          throw new RuntimeException();
        }
        do {
          Bytes nameTxn = query.term();
          int nameTxnLen = nameTxn.getLength();
          long txn = Util.beBytesToLong(nameTxn.getBytes(nameTxnLen - 8, 8), 0);
          if (txn > headTxn) headTxn = txn;
        } while (query.positionNext());
        docId = query.nextValidDocId(docId + 1);
      } while (docId < Long.MAX_VALUE);
//      do {
//        long txn = Util.beBytesToLong(query.term().getBytes(0, 8), 0);
//        if (txn > headTxn) headTxn = txn;
//      } while (query.next());
    }
  }
 
  public FsTransactionMapper(File file, boolean sync) {
    map = new FsBlueSteelBagIndex(sync);
    File mapDir = new File(file, "txnmap");
    if (!mapDir.mkdir()) throw new RuntimeException("Cannot create transaction map");
    map.setHomedir(mapDir.getAbsolutePath());
  }

  public String toString() {
    return "FsTransactionMapper(head="+headTxn+", "+map+")";
  }
 
  public synchronized void addRevsForTxn(long txn, Map<String, Long> revNums) {
    ArrayList<EditRec> edits = new ArrayList<EditRec>(revNums.size());
    for(Map.Entry<String,Long> bagRev : revNums.entrySet()) {
      Bytes bytes = termForTxnBag(bagRev.getKey(), txn);
      edits.add(new EditRec(bagRev.getValue(), bytes, false));
    }
    map.commitNewRev(edits);
    if (txn > headTxn) headTxn = txn;
    nextReserved = false;
  }

  protected Bytes termForTxnBag(String bag, long txn) {
    byte[] bagNameBytes = bag.getBytes();
    byte[] revNumBytes = new byte[9];
    Util.beLongToBytes(txn, revNumBytes, 1);
    return new CompoundBytes(
        new ArrayBytes(bagNameBytes),
        new ArrayBytes(revNumBytes));
  }
 
  public long getRevForTxn(String bag, long txnIdthrows TxnNotFoundException {
    long mapRevNum = map.getCurrentRevNum();
    Range range = new Range(ArrayBytes.EMPTY_BYTES, null, null, true, true);
    range.setBoundsAndExtractPrefix(
        termForTxnBag(bag, 0),
        termForTxnBag(bag, txnId));
    QueryNode query = map.getRange(range, mapRevNum);
    long revNum = 0;
    if (query != null) {
      do {
        long curRev = query.doc();
        if (curRev > revNum) revNum = curRev;
      } while(query.nextTerm() != NextStatus.AT_END);
    }
    return revNum;
    /*
    QueryNode query = map.getTerm(termForTxnBag(txnId, bag), revNum);
    if (query != null) {
      return query.doc();
    } else {
      Range range = new Range(termForTxnBag(txnId, ""), null, null, true, true);
      query = map.getRange(range, revNum);
      if (query == null) {
        throw new TxnNotFoundException(txnId);
      } else {
        return 0;
      }
    }
    */
  }

  public long reserveTxnId() {
    if (nextReserved) throw new RuntimeException("Previous transaction not resolved");
    nextReserved = true;
    return getHighestTxnId() + 1;
  }

  public long getHighestTxnId() {
    return headTxn;
  }
 
}
TOP

Related Classes of dovetaildb.dbservice.FsTransactionMapper

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.