+++ /dev/null
-package org.apache.lucene.search.suggest.tst;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.lucene.search.suggest.Lookup;
-import org.apache.lucene.search.suggest.SortedTermFreqIteratorWrapper;
-import org.apache.lucene.search.spell.SortedIterator;
-import org.apache.lucene.search.spell.TermFreqIterator;
-
-public class TSTLookup extends Lookup {
- TernaryTreeNode root = new TernaryTreeNode();
- TSTAutocomplete autocomplete = new TSTAutocomplete();
-
- @Override
- public void build(TermFreqIterator tfit) throws IOException {
- root = new TernaryTreeNode();
- // buffer first
- if (!(tfit instanceof SortedIterator)) {
- // make sure it's sorted
- tfit = new SortedTermFreqIteratorWrapper(tfit);
- }
-
- ArrayList<String> tokens = new ArrayList<String>();
- ArrayList<Float> vals = new ArrayList<Float>();
- while (tfit.hasNext()) {
- tokens.add(tfit.next());
- vals.add(new Float(tfit.freq()));
- }
- autocomplete.balancedTree(tokens.toArray(), vals.toArray(), 0, tokens.size() - 1, root);
- }
-
- @Override
- public boolean add(String key, Object value) {
- autocomplete.insert(root, key, value, 0);
- // XXX we don't know if a new node was created
- return true;
- }
-
- @Override
- public Object get(String key) {
- List<TernaryTreeNode> list = autocomplete.prefixCompletion(root, key, 0);
- if (list == null || list.isEmpty()) {
- return null;
- }
- for (TernaryTreeNode n : list) {
- if (n.token.equals(key)) {
- return n.val;
- }
- }
- return null;
- }
-
- @Override
- public List<LookupResult> lookup(String key, boolean onlyMorePopular, int num) {
- List<TernaryTreeNode> list = autocomplete.prefixCompletion(root, key, 0);
- List<LookupResult> res = new ArrayList<LookupResult>();
- if (list == null || list.size() == 0) {
- return res;
- }
- int maxCnt = Math.min(num, list.size());
- if (onlyMorePopular) {
- LookupPriorityQueue queue = new LookupPriorityQueue(num);
- for (TernaryTreeNode ttn : list) {
- queue.insertWithOverflow(new LookupResult(ttn.token, (Float)ttn.val));
- }
- for (LookupResult lr : queue.getResults()) {
- res.add(lr);
- }
- } else {
- for (int i = 0; i < maxCnt; i++) {
- TernaryTreeNode ttn = list.get(i);
- res.add(new LookupResult(ttn.token, (Float)ttn.val));
- }
- }
- return res;
- }
-
- public static final String FILENAME = "tst.dat";
-
- private static final byte LO_KID = 0x01;
- private static final byte EQ_KID = 0x02;
- private static final byte HI_KID = 0x04;
- private static final byte HAS_TOKEN = 0x08;
- private static final byte HAS_VALUE = 0x10;
-
- @Override
- public synchronized boolean load(File storeDir) throws IOException {
- File data = new File(storeDir, FILENAME);
- if (!data.exists() || !data.canRead()) {
- return false;
- }
- DataInputStream in = new DataInputStream(new FileInputStream(data));
- root = new TernaryTreeNode();
- try {
- readRecursively(in, root);
- } finally {
- in.close();
- }
- return true;
- }
-
- // pre-order traversal
- private void readRecursively(DataInputStream in, TernaryTreeNode node) throws IOException {
- node.splitchar = in.readChar();
- byte mask = in.readByte();
- if ((mask & HAS_TOKEN) != 0) {
- node.token = in.readUTF();
- }
- if ((mask & HAS_VALUE) != 0) {
- node.val = new Float(in.readFloat());
- }
- if ((mask & LO_KID) != 0) {
- node.loKid = new TernaryTreeNode();
- readRecursively(in, node.loKid);
- }
- if ((mask & EQ_KID) != 0) {
- node.eqKid = new TernaryTreeNode();
- readRecursively(in, node.eqKid);
- }
- if ((mask & HI_KID) != 0) {
- node.hiKid = new TernaryTreeNode();
- readRecursively(in, node.hiKid);
- }
- }
-
- @Override
- public synchronized boolean store(File storeDir) throws IOException {
- if (!storeDir.exists() || !storeDir.isDirectory() || !storeDir.canWrite()) {
- return false;
- }
- File data = new File(storeDir, FILENAME);
- DataOutputStream out = new DataOutputStream(new FileOutputStream(data));
- try {
- writeRecursively(out, root);
- out.flush();
- } finally {
- out.close();
- }
- return true;
- }
-
- // pre-order traversal
- private void writeRecursively(DataOutputStream out, TernaryTreeNode node) throws IOException {
- // write out the current node
- out.writeChar(node.splitchar);
- // prepare a mask of kids
- byte mask = 0;
- if (node.eqKid != null) mask |= EQ_KID;
- if (node.loKid != null) mask |= LO_KID;
- if (node.hiKid != null) mask |= HI_KID;
- if (node.token != null) mask |= HAS_TOKEN;
- if (node.val != null) mask |= HAS_VALUE;
- out.writeByte(mask);
- if (node.token != null) out.writeUTF(node.token);
- if (node.val != null) out.writeFloat((Float)node.val);
- // recurse and write kids
- if (node.loKid != null) {
- writeRecursively(out, node.loKid);
- }
- if (node.eqKid != null) {
- writeRecursively(out, node.eqKid);
- }
- if (node.hiKid != null) {
- writeRecursively(out, node.hiKid);
- }
- }
-}