package com.splicemachine.si.impl;

import com.splicemachine.si.api.TransactionStatus;

import java.io.IOException;

public class DDLFilter implements Comparable<DDLFilter> {
    private final Transaction myTransaction;
		private final Transaction myParentTransaction;
    private final TransactionStore transactionStore;

    public DDLFilter(
            Transaction myTransaction,
						Transaction myParentTransaction,
            TransactionStore transactionStore) {
        super();
        this.myTransaction = myTransaction;
        this.transactionStore = transactionStore;
				this.myParentTransaction = myParentTransaction;
    }

    public boolean isVisibleBy(String transactionId) throws IOException {
				//if I didn't succeed, don't do anything
				if(myTransaction.getEffectiveStatus()!= TransactionStatus.COMMITTED) return false;
				//if I have a parent, and he was rolled back, don't do anything
				if(myParentTransaction!=null && myParentTransaction.getEffectiveStatus()==TransactionStatus.ROLLED_BACK) return false;

        Transaction transaction = transactionStore.getTransaction(new TransactionId(transactionId));
				/*
				 * For the purposes of DDL, we intercept any writes which occur AFTER us, regardless of
				 * my status.
				 *
				 * The reason for this is because the READ of us will not see those writes, which means
				 * that we need to intercept them and deal with them as if we were committed. If we rollback,
				 * then it shouldn't matter to the other operation (except for performance), and if we commit,
				 * then we should see properly constructed data.
				 */
				long otherTxnId = transaction.getLongTransactionId();
				return myTransaction.getLongTransactionId()<=otherTxnId;
//				// TODO use cache here
//        return transaction.canSee(myTransaction, new TransactionSource() {
//            @Override
//            public Transaction getTransaction(long timestamp) throws IOException {
//                return transactionStore.getTransaction(timestamp);
//            }
//        }).visible;
    }

    public Transaction getTransaction() {
        return myTransaction;
    }

    @Override
    public int compareTo(DDLFilter o) {
        if (o == null) {
            return 1;
        }
        if (myTransaction.getStatus().isCommitted()) {
            if (o.getTransaction().getStatus().isCommitted()) {
                return compare(myTransaction.getCommitTimestampDirect(), o.getTransaction().getCommitTimestampDirect());
            } else {
                return 1;
            }
        } else {
            if (o.getTransaction().getStatus().isCommitted()) {
                return -1;
            } else {
                return compare(myTransaction.getEffectiveBeginTimestamp(), o.getTransaction().getEffectiveBeginTimestamp());
            }
        }
    }

    private static int compare(long my, long other) {
        if (my > other) {
            return 1;
        } else if (my < other) {
            return -1;
        } else {
            return 0;
        }
    }
}

@@ -80,16 +80,41 @@
 Status;%0A
+import java.util.HashMap;
 %0Aimport 
@@ -238,17 +238,16 @@
 action;%0A
-%09
 %09private
@@ -338,16 +338,68 @@
 onStore;
+%0A    private HashMap%3CString, Boolean%3E visibilityMap;
 %0A%0A    pu
@@ -455,20 +455,20 @@
 tion,%0A%09%09
-%09%09%09%09
+    
 Transact
@@ -652,18 +652,16 @@
 nStore;%0A
-%09%09
 %09%09this.m
@@ -694,32 +694,88 @@
 entTransaction;%0A
+        visibilityMap = new HashMap%3CString, Boolean%3E();%0A
     %7D%0A%0A    publi
@@ -839,16 +839,192 @@
 ption %7B%0A
+                Boolean visible = visibilityMap.get(transactionId);%0A                if (visible != null) %7B%0A                    return visible.booleanValue();%0A                %7D%0A
 %09%09%09%09//if
@@ -1339,16 +1339,24 @@
 false;%0A%0A
+        
         
@@ -1980,16 +1980,129 @@
 onId();%0A
+                visibilityMap.put(transactionId, new Boolean(myTransaction.getLongTransactionId()%3C=otherTxnId));%0A
 %09%09%09%09retu

add a cache to DDLFilter to improve worday query 27