1 package com.hughes.android.dictionary;
\r
2 //package com.hughes.android.dictionary;
\r
4 //import java.io.IOException;
\r
5 //import java.io.RandomAccessFile;
\r
6 //import java.util.Map;
\r
7 //import java.util.Set;
\r
8 //import java.util.TreeMap;
\r
10 //import com.hughes.util.LRUCacheMap;
\r
13 //public final class Index {
\r
15 // final String filename;
\r
16 // final RandomAccessFile file;
\r
19 // final Map<Integer,Node> indexOffsetToNode = new LRUCacheMap<Integer,Node>(5000);
\r
22 // public Index(final String filename) throws IOException {
\r
23 // this.filename = filename;
\r
24 // file = new RandomAccessFile(filename, "r");
\r
25 // root = getNode(new NodeHandle("", 0));
\r
28 // public Node lookup(final String normalizedToken) throws IOException {
\r
29 // return lookup(normalizedToken, 0, root);
\r
32 // private Node lookup(final String normalizedToken, final int pos, final Node node) throws IOException {
\r
33 // if (pos == normalizedToken.length()) {
\r
37 // // Check whether any prefix of the token is a child.
\r
38 // for (int i = pos + 1; i <= normalizedToken.length(); ++i) {
\r
39 // final NodeHandle childHandle = node.children.get(normalizedToken.substring(pos, i));
\r
40 // if (childHandle != null) {
\r
41 // return lookup(normalizedToken, i, childHandle.getNode());
\r
45 // // Check whether any child starts with what's left of text.
\r
46 // final String remainder = normalizedToken.substring(pos);
\r
47 // for (final Map.Entry<String, NodeHandle> childHandle : node.children.entrySet()) {
\r
48 // if (childHandle.getKey().startsWith(remainder)) {
\r
49 // return getNode(childHandle.getValue());
\r
56 // private Node getNode(final NodeHandle nodeHandle) throws IOException {
\r
57 // Node node = indexOffsetToNode.get(nodeHandle.indexOffset);
\r
58 // if (node == null) {
\r
59 // node = new Node(nodeHandle);
\r
60 // indexOffsetToNode.put(nodeHandle.indexOffset, node);
\r
65 // final class NodeHandle {
\r
66 // final String normalizedToken;
\r
67 // final int indexOffset;
\r
69 // NodeHandle(final String normalizedToken, final int indexOffset) throws IOException {
\r
70 // this.normalizedToken = normalizedToken;
\r
71 // this.indexOffset = indexOffset;
\r
74 // Node getNode() throws IOException {
\r
75 // return Index.this.getNode(this);
\r
79 // final class Node {
\r
80 // final NodeHandle nodeHandle;
\r
81 // final TreeMap<String,NodeHandle> children;
\r
82 // final Map<String,int[]> tokenToOffsets = new TreeMap<String, int[]>(EntryFactory.entryFactory.getTokenComparator());
\r
83 // final int descendantTokenCount;
\r
84 // final int descendantEntryCount;
\r
86 // Node(final NodeHandle nodeHandle) throws IOException {
\r
87 // this.nodeHandle = nodeHandle;
\r
89 // file.seek(nodeHandle.indexOffset);
\r
91 // // Read children to offset.
\r
92 // final int numChildren = file.readInt();
\r
93 // children = new TreeMap<String, NodeHandle>();
\r
94 // for (int i = 0; i < numChildren; ++i) {
\r
95 // final String chunk = file.readUTF().intern();
\r
96 // if (chunk.length() == 0) {
\r
97 // throw new IOException("Empty string chunk.");
\r
99 // children.put(chunk, new NodeHandle(nodeHandle.normalizedToken + chunk, file.readInt()));
\r
103 // final int numTokens = file.readInt();
\r
104 // for (int i = 0; i < numTokens; ++i) {
\r
105 // final String token = file.readUTF();
\r
106 //// assert EntryFactory.entryFactory.normalizeToken(token).equals(nodeHandle.normalizedToken);
\r
107 // final int[] offsets = new int[file.readInt()];
\r
108 // for (int j = 0; j < offsets.length; ++j) {
\r
109 // offsets[j]= file.readInt();
\r
111 // tokenToOffsets.put(token, offsets);
\r
114 // // TODO: move this up, and defer the loading of the other stuff until it's needed.
\r
115 // descendantTokenCount = file.readInt();
\r
116 // descendantEntryCount = file.readInt();
\r
120 // public String toString() {
\r
121 // return String.format("%s(%d,%d)", nodeHandle.normalizedToken, getThisCount(), getDescendantCount());
\r
124 // public int getDescendantCount() {
\r
125 // return descendantEntryCount + descendantTokenCount;
\r
128 // public int getThisCount() {
\r
129 // int count = tokenToOffsets.size();
\r
130 // for (final int[] offsets : tokenToOffsets.values()) {
\r
131 // count += offsets.length;
\r
136 // public Object getDescendant(int position) throws IOException {
\r
137 // assert position < getDescendantCount();
\r
139 //// System.out.println("getD: " + this + ", " + position);
\r
140 // if (position < getThisCount()) {
\r
141 // for (final Map.Entry<String, int[]> tokenEntry : tokenToOffsets.entrySet()) {
\r
142 // if (position == 0) {
\r
143 // return tokenEntry.getKey();
\r
146 // if (position < tokenEntry.getValue().length) {
\r
147 // return tokenEntry.getValue()[position];
\r
149 // position -= tokenEntry.getValue().length;
\r
153 // position -= getThisCount();
\r
156 // for (final Map.Entry<String,NodeHandle> childEntry : children.entrySet()) {
\r
157 // final Node child = childEntry.getValue().getNode();
\r
158 // if (position < child.getDescendantCount()) {
\r
159 // return child.getDescendant(position);
\r
161 // position -= child.getDescendantCount();
\r
167 // public void getDescendantEntryOffsets(final Set<Integer> entryOffsets, int maxSize) throws IOException {
\r
168 // for (final int[] offsets : tokenToOffsets.values()) {
\r
169 // for (final int offset : offsets) {
\r
170 // if (entryOffsets.size() >= maxSize) {
\r
173 // entryOffsets.add(offset);
\r
176 // if (entryOffsets.size() >= maxSize) {
\r
179 // for (final Map.Entry<String, NodeHandle> childEntry : children.entrySet()) {
\r
180 // final Node child = childEntry.getValue().getNode();
\r
181 // child.getDescendantEntryOffsets(entryOffsets, maxSize);
\r
182 // if (entryOffsets.size() >= maxSize) {
\r