Package dovetaildb.dbservice

Source Code of dovetaildb.dbservice.DbResult

package dovetaildb.dbservice;

import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import org.json.simple.JSONAware;
import org.json.simple.JSONObject;
import org.json.simple.JSONStreamAware;
import org.json.simple.JSONValue;

import dovetaildb.bytes.ArrayBytes;
import dovetaildb.bytes.Bytes;
import dovetaildb.bytes.CompoundBytes;
import dovetaildb.bytes.SlicedBytes;

public class DbResult implements JSONAware, JSONStreamAware {
 
  Bytes prefix = ArrayBytes.EMPTY_BYTES;
  Bytes suffix = null;
  SpecializableQueryNode node;
  DbResultMap asMap = null;
  DbResultList asList = null;
  HashMap<String, DbResult> byObjectKey = new HashMap<String, DbResult>();
  ArrayList<DbResult> byArrayIndex = new ArrayList<DbResult>();

  // these change per result:
  Bytes firstTerm;
  char type;
  ArrayList<String> mapKeys = null;
 
 
  public Object simplify() {
    switch (type) {
    case 'l': return null;
    case 's': return getString();
    case 'n': return getDouble();
    case 't': return Boolean.TRUE;
    case 'f': return Boolean.FALSE;
    case '[': return asList;
    case '{': return asMap;
    }
  }
 
 
 
 
 
  public Bytes[] terms = new Bytes[]{null,null,null,null};
  int numTerms = 0;
 
  public char getType() { return (char)terms[0].get(0); }
 
  private static int binarySearch(Comparable[] a, Comparable x, int highestValidIndex) {
        int low = 0;
        int high = highestValidIndex;
        int mid;
        while( low <= high ) {
            mid = ( low + high ) / 2;
            if( a[mid].compareTo( x ) < 0 )
                low = mid + 1;
            else if( a[mid].compareTo( x ) > 0 )
                high = mid - 1;
            else
                return mid;
        }
        return low;
    }
 
  public DbResult derefByKey(String key) {
    Bytes cmpKey = new CompoundBytes(DbServiceUtil.HEADER_BYTE_MAPOPEN,
        new CompoundBytes(DbServiceUtil.sencodeMapKey(key),
            DbServiceUtil.HEADER_BYTE_COLON));
    int keyLen = cmpKey.getLength();
    int idx = binarySearch(terms, cmpKey, numTerms);
    Bytes[] subTerms = new Bytes[numTerms-idx]; // at most this many elements
    int subIdx = 0;
    for(;idx<numTerms;idx++) {
      Bytes curTerm = terms[idx];
      if (cmpKey.isPrefixOf(curTerm)) {
        subTerms[subIdx++] = curTerm.subBytes(keyLen, curTerm.getLength()-keyLen);
      } else {
        break;
      }
    }
    if (subIdx == 0) return null; // as opposed to a DbResult representing null
    DbResult next = new DbResult();
    next.terms = subTerms;
    next.numTerms = subIdx;
    return next;
  }

  public DbResult derefByIndex(int index) {
    int hiIdxByte = index >> 8;
    int loIdxByte = index & 0xff;
    Bytes[] subTerms = new Bytes[numTerms]; // at most this many elements
    int subIdx = 0;
    for(int termIdx=0; termIdx<this.numTerms; termIdx++) {
      Bytes term = terms[termIdx];
      if (term.get(0) != '[') continue;
      int sz = term.getLength();
      if (term.get(sz-1) == loIdxByte && term.get(sz-2) == hiIdxByte) {
        subTerms[subIdx++] = SlicedBytes.make(term, 1, sz-3);
      }
    }
    DbResult next = new DbResult();
    next.terms = subTerms;
    next.numTerms = subIdx;
    return next;
  }

  public Collection<String> getObjectKeys() {
    // TODO: optimize this a bit
    HashSet<String> keys = new HashSet<String>(terms.length);
    for(int termIdx=0; termIdx<this.numTerms; termIdx++) {
      Bytes term = terms[termIdx];
      int len = term.getLength();
      for(int i=1; i<len; i++) {
        if (term.get(i) == ':') {
          try {
            keys.add(new String(term.subBytes(1, i-1).getBytes(), "utf-8"));
          } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
          }
          break;
        }
      }
    }
    return keys;
  }
 
  public int getArrayLength() {
    int maxIdx = -1;
    for(int termIdx=0; termIdx<this.numTerms; termIdx++) {
      Bytes term = terms[termIdx];
      int sz = term.getLength();
      int idx = (term.get(sz-2)<<8) | term.get(sz-1);
      if (idx > maxIdx) maxIdx = idx;
    }
    return maxIdx+1;
 
 
  public String getString() {
    try {
      Bytes term = terms[0];
      byte[] bytes = new byte[term.getLength()-1];
      term.writeBytes(1, bytes);
      return new String(bytes, "utf-8");
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
  }

  public boolean isString() {
    return terms[0].get(0) == 's';
  }
 
  public boolean isObject() {
    return terms[0].get(0) == '{';
  }

  public boolean isArray() {
    return terms[0].get(0) == '[';
  }

  public boolean isNull() {
    return terms[0].get(0) == 'l';
  }
 
  public boolean getBoolean() {
    switch (terms[0].get(0)) {
    case 't': return true;
    case 'f': return false;
    default: throw new RuntimeException();
    }
  }
 
  public double getDouble() {
    Bytes term = terms[0];
    if (term.get(0) != 'n') throw new RuntimeException();
    long bits = (((long)term.get(1)) << 8 * 7) |
          (((long)term.get(2)&0xFF) << 8 * 6) |
          (((long)term.get(3)&0xFF) << 8 * 5) |
          (((long)term.get(4)&0xFF) << 8 * 4) |
          (((long)term.get(5)&0xFF) << 8 * 3) |
          (((long)term.get(6)&0xFF) << 8 * 2) |
          (((long)term.get(7)&0xFF) << 8 * 1) |
          (((long)term.get(8)&0xFF) << 8 * 0);
   
    // see sencode for why we do these bit manipulations:
    if ((bits & 0x8000000000000000L) == 0) {
      bits ^= 0xFFFFFFFFFFFFFFFFL;
    } else {
      bits ^= 0x8000000000000000L;
    }
    return Double.longBitsToDouble(bits);
  }
 
  public DbResult() {
  }
  public void clearTerms() {
    numTerms=0;
  }
  public void addTerm(Bytes bytes) {
    if (numTerms >= terms.length) {
      Bytes[] newTerms = new Bytes[(terms.length*3)/2];
      System.arraycopy(terms, 0, newTerms, 0, terms.length);
      terms = newTerms;
    }
    terms[numTerms] = bytes.copyInto(terms[numTerms]);
    numTerms++;
  }
 
  public void writeJSONString(Writer w) throws IOException {
    if (numTerms < 1) {
      throw new RuntimeException();
    }
    switch(terms[0].get(0)) {
    case 'l': w.write("null"); break;
    case 't': w.write("true"); break;
    case 'f': w.write("false"); break;
    case 'n': w.write(Double.toString(getDouble())); break;
    case 's':
      w.write('"');
      w.write(JSONObject.escape(getString()));
      w.write('"');
      break;
    case '{':
      w.write('{');
      boolean first = true;
      for(String key:getObjectKeys()) {
        if (first) first=false;
        else w.write(',');
        w.write('"');
        w.write(key);
        w.write("\":");
        derefByKey(key).writeJSONString(w);
      }
      w.write('}');
      break;
    case '[':
      w.write('[');
      for(int i=0; i<getArrayLength(); i++) {
        if (i>0) w.write(',');
        derefByIndex(i).writeJSONString(w);
      }
      w.write(']');
      break;
    default:
      throw new RuntimeException();
    }
   
  }

  public String toJSONString() {
    StringWriter w = new StringWriter();
    try {
      writeJSONString(w);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    return w.toString();
  }

 
//  public Set entrySet() {
//    return new AbstractSet() {
//      @Override
//      public Iterator iterator() {
//        return new Iterator() {
//          int i=0;
//          public boolean hasNext() {
//            return (i < numTerms-1);
//          }
//          public Object next() {
//            return terms[++i];
//          }
//          public void remove() {
//            throw new RuntimeException();
//          }
//       
//        };
//      }
//      @Override
//      public int size() { return numTerms; }
//    };
//  }
 
}
TOP

Related Classes of dovetaildb.dbservice.DbResult

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.