package core.index.kdtree;

import core.index.MDIndex;
import core.index.key.MDIndexKey;
import core.utils.SchemaUtils.TYPE;

import java.util.List;

/**
 * Created by qui on 1/31/15.
 */
public class KDNode {

    private int dimension;
    private Comparable value;
    private int numBuckets;

    private KDNode parent;
    private KDNode leftChild;
    private KDNode rightChild;

    public KDNode() {
        numBuckets = 1;
    }

    public int getDimension() {
        return dimension;
    }

    public int getNumBuckets() {
        return numBuckets;
    }

    public void setValues(int dimension, TYPE type, MDIndexKey key) {
        this.dimension = dimension;
        switch (type) {
            case INT:
                this.value = key.getIntAttribute(dimension);
                break;
            case LONG:
                this.value = key.getLongAttribute(dimension);
                break;
            case FLOAT:
                this.value = key.getFloatAttribute(dimension);
                break;
            case DATE:
                this.value = (Comparable) key.getDateAttribute(dimension);
                break;
            case STRING:
                this.value = key.getStringAttribute(dimension, 20);
                break;
            default:
                throw new RuntimeException("Unknown dimension type: "+type);
        }
        // TODO(qui): deal with VARCHAR somewhere
    }

    public KDNode insert(MDIndexKey key) {
        if (value == null) {
            return this;
        } else if (value.compareTo(key.getIntAttribute(dimension)) >= 0) {
            if (leftChild == null) {
                leftChild = new KDNode();
                leftChild.parent = this;
                if (rightChild != null) {
                    numBuckets = rightChild.getNumBuckets() + 1;
                }
                return leftChild;
            } else {
                return leftChild.insert(key);
            }
        } else {
            if (rightChild == null) {
                rightChild = new KDNode();
                rightChild.parent = this;
                if (leftChild != null) {
                    numBuckets = leftChild.getNumBuckets() + 1;
                }
                return rightChild;
            } else {
                return rightChild.insert(key);
            }
        }
    }

    public int getBucketId(MDIndexKey key, int start) {
        if (numBuckets == 1) {
            return start;
        }
        int searchVal = key.getIntAttribute(dimension);
        if (value.compareTo(searchVal) >= 0) {
            return leftChild.getBucketId(key, start*2);
        }
        else {
            return rightChild.getBucketId(key, start*2+1);
        }
    }

    public List<MDIndex.Bucket> rangeSearch(MDIndexKey low, MDIndexKey high) {
        return null;
    }
}

@@ -227,24 +227,47 @@
  dimension;%0A
+    private TYPE type;%0A
     private 
@@ -689,24 +689,186 @@
  dimension;%0A
+        this.type = type;%0A        this.value = getValue(dimension, type, key);%0A    %7D%0A%0A    private Comparable getValue(int dimension, TYPE type, MDIndexKey key) %7B%0A
         swit
@@ -913,36 +913,30 @@
             
-this.value =
+return
  key.getIntA
@@ -956,39 +956,16 @@
 nsion);%0A
-                break;%0A
         
@@ -991,36 +991,30 @@
             
-this.value =
+return
  key.getLong
@@ -1035,39 +1035,16 @@
 nsion);%0A
-                break;%0A
         
@@ -1071,36 +1071,30 @@
             
-this.value =
+return
  key.getFloa
@@ -1116,39 +1116,16 @@
 nsion);%0A
-                break;%0A
         
@@ -1155,28 +1155,22 @@
         
-this.value =
+return
  (Compar
@@ -1208,39 +1208,16 @@
 nsion);%0A
-                break;%0A
         
@@ -1249,28 +1249,22 @@
         
-this.value =
+return
  key.get
@@ -1299,31 +1299,8 @@
 0);%0A
-                break;%0A
     
@@ -1452,32 +1452,199 @@
 omewhere%0A    %7D%0A%0A
+    private void incrementNumBuckets() %7B%0A        this.numBuckets++;%0A        if (this.parent != null) %7B%0A            this.parent.incrementNumBuckets();%0A        %7D%0A    %7D%0A%0A
     public KDNod
@@ -1763,37 +1763,37 @@
 eTo(
-key.getIntAttribute(dimension
+getValue(dimension, type, key
 )) %3E
@@ -1946,25 +1946,25 @@
 (rightChild 
-!
+=
 = null) %7B%0A  
@@ -1994,29 +1994,54 @@
 ckets = 
-rightChild.ge
+2;%0A                    parent.incremen
 tNumBuck
@@ -2037,36 +2037,32 @@
 mentNumBuckets()
- + 1
 ;%0A              
@@ -2350,17 +2350,17 @@
 ftChild 
-!
+=
 = null) 
@@ -2394,28 +2394,54 @@
 ckets = 
-leftChild.ge
+2;%0A                    parent.incremen
 tNumBuck
@@ -2449,12 +2449,8 @@
 ts()
- + 1
 ;%0A  
@@ -2667,250 +2667,353 @@
     
-if (numBuckets == 1) %7B%0A            return start;%0A        %7D%0A        int searchVal = key.getIntAttribute(dimension);%0A        if (value.compareTo(searchVal) %3E= 0) %7B%0A            return leftChild.getBucketId(key, start*2);%0A        %7D%0A        else %7B
+Comparable searchVal = getValue(dimension, type, key);%0A        if (value.compareTo(searchVal) %3E= 0) %7B%0A            if (leftChild == null) %7B%0A                return start;%0A            %7D%0A            return leftChild.getBucketId(key, start*2);%0A        %7D%0A        else %7B%0A            if (rightChild == null) %7B%0A                return start;%0A            %7D
 %0A   

Update bucket id stuff for kd