All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xapi.collect.trie.DeepTrieEdge Maven / Gradle / Ivy

There is a newer version: 0.5
Show newest version
package xapi.collect.trie;

import xapi.collect.api.StringTrie;
import xapi.collect.api.StringTrie.StringTrieCursor;
import xapi.collect.api.StringTrie.StringTrieEdge;
import xapi.util.impl.Chars;
import xapi.util.impl.Chars.SingleChar;

public class DeepTrieEdge  implements StringTrie.StringTrieEdge{

  private static final SingleChar[] COMMON_CHARS = new SingleChar['_'];
  static {
    for (int i = '_';i-->0;)
      COMMON_CHARS[i] = new SingleChar((char)i);
  }

  protected class DeepTrieCursor implements StringTrie.StringTrieCursor {

    private final SingleChar key;
    private final StringTrieEdge edge;

    public DeepTrieCursor(char k, StringTrieEdge edge) {
      if (k < COMMON_CHARS.length) {
        this.key = COMMON_CHARS[k];
      } else {
        this.key = new Chars.SingleChar(k);
      }
      this.edge = edge;
    }

    @Override
    public final CharSequence key() {
      return key;
    }

    @Override
    public final int consumed() {
      return 1;
    }

    @Override
    public final StringTrieEdge edge() {
      return edge;
    }

  }

  //The depth, in characters, for this element
  private final int depth;
  //The sequence of characters leading up to this node
  private final CharSequence key;
  //The value, if any, stored at this node
  private volatile E value;

  //Remember our highest and lowest chars to make add-to-either-end efficient
  private volatile char lowest;
  private volatile char highest;
  //These are counts for the number of lower and higher elements
  //We use char because there cannot be more array indices than there are chars.
  private volatile char lowerUsed;
  private volatile char higherUsed;
//  // A cursor for speedy gets of the same value
//  // This is not volatile because thread caching here is good.
//  private int lastGet;
  //The array
  private StringTrieEdge[] edges;

  public DeepTrieEdge(CharSequence key, int depth, E value) {
    this(key, depth, value, 9);
  }
  @SuppressWarnings("unchecked")
  public DeepTrieEdge(CharSequence key, int depth, E value, int initialSize) {
    this.depth = depth;
    this.key = key;
    this.value = value;
    this.edges = new StringTrieEdge[initialSize/2];
  }

  public synchronized DeepTrieEdge addEdge(StringTrieEdge edge) {
    final CharSequence key = edge.key();
    if (key.length() == 0) {
      //we're adding another deep edge
    } else {
      final char k = key.charAt(0);
      final int deltaLower = k - lowest;
      if (deltaLower < 0) {
        // we have a new lowest

        lowest = k;
      }
      final int deltaHigher = k - highest;
      if (deltaHigher > 0) {
        // we have a new highest.  First insert will go here.

        highest = k;
      }
      // no easy insert; perform binary search
      int pos = lowerUsed - 1;
      StringTrieEdge biggestLow = edges[pos];
      int deltaBottom;
      searchLower:
      if (biggestLow == null) {
        deltaBottom = Integer.MIN_VALUE;
      } else {
        assert biggestLow.key().length() > 0;
        char test = biggestLow.key().charAt(0);
        deltaBottom = k - test;
        if (deltaBottom == 0) {// optimistic search
          addInto(biggestLow, edge);
          return this;
        }
        if (deltaBottom < 0) {
          // no need to consult highest.  search down from our "highest lowest"
          while (test > 0) {
            if (--pos < 0)
              break searchLower;
            biggestLow = edges[pos];
            if (biggestLow == null)
              break searchLower;
            test = biggestLow.key().charAt(0);
            deltaBottom = k - test;
            if (deltaBottom == 0) {
              addInto(biggestLow, edge);
              return this;
            }
            if (deltaBottom > 0) {
              // inserted node is higher than this lowest
              addAfterLower(biggestLow, edge, pos);
              return this;
            }
          }
        }
      }

      // Nothing found in lesser
      // Start searching the higher
      pos = edges.length - higherUsed;
      StringTrieEdge lowestHigh = edges[pos];
      int deltaTop;
      searchHigher:
      if (lowestHigh != null) {
        assert lowestHigh.key().length() > 0;
        char test = lowestHigh.key().charAt(0);
        deltaTop = k - test;
        if (deltaTop== 0) {// optimistic search
          addInto(lowestHigh, edge);
          return this;
        }
        if (deltaTop > 0) {
          // we are greater than the lowest high value, so we must search
          while (test > 0) {
            if (++pos >= edges.length)
              break searchHigher;
            lowestHigh = edges[pos];
            if (lowestHigh == null)
              break searchHigher;
            test = lowestHigh.key().charAt(0);
            deltaTop = k - test;
            if (deltaTop== 0) {
              addInto(lowestHigh, edge);
              return this;
            }
            if (deltaTop < 0) {
              // inserted node is less than this highest
              addBeforeHigher(lowestHigh, edge, pos);
              return this;
            }
          }
          // Inserted edge is greater
        }
      }
      // Neither top nor bottom encloses this char,
      // And it's not a max or min, thus, it must be between higher and lower.
      // We choose to add it to the side that has the fewest elements
      // TODO finish this
    }
    return this;
  }

  private void addBeforeHigher(StringTrieEdge biggestLow, StringTrieEdge edge, int pos) {

  }
  private void addAfterLower(StringTrieEdge biggestLow, StringTrieEdge edge, int pos) {

  }
  private void addInto(StringTrieEdge into, StringTrieEdge edge) {

  }
  @Override
  public int depth() {
    return depth;
  }

  @Override
  public CharSequence key() {
    return key;
  }

  @Override
  public E value() {
    return value;
  }
  @Override
  public E addValue(CharSequence key, int keyFrom, E value) {
    if (key.length() == 0 || keyFrom == key.length() - 1) {
      E ret = this.value;
      this.value = value;
      return ret;
    }
    StringTrieCursor cursor = hasEdge(key, keyFrom);
    if (cursor == null) {

    } else {
      StringTrieEdge into = cursor.edge();
      return into.addValue(key, keyFrom+1, value);
    }

    return null;
  }
  @Override
  public StringTrieCursor hasEdge(CharSequence key, int keyFrom) {
    return null;
  }
  @Override
  public StringTrieEdge highest() {
    return edges[edges.length-1];
  }
  @Override
  public StringTrieEdge lowest() {
    return edges[0];
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy