1 package org.paneris.bibliomania.fti;
2
3 import org.melati.poem.util.Order;
4 import org.melati.poem.util.SortUtils;
5
6 import com.sleepycat.db.DatabaseException;
7
8 public class AndSearchResults implements SearchResults {
9 private static final Order leastCommonFirst = new Order() {
10 public boolean lessOrEqual(Object a, Object b) {
11 return ((SearchResults)a).frequency() < ((SearchResults)b).frequency();
12 }
13 };
14
15 private SearchResults[] streams;
16 private long textID = -1;
17 private boolean grouped;
18 private TextSearchResults occurrences;
19 private int frequency;
20
21 private void construct() {
22 frequency = Integer.MAX_VALUE;
23 for (int w = 0; w < streams.length; ++w)
24 frequency = Math.min(streams[w].frequency(), frequency);
25
26 SortUtils.insertionSort(leastCommonFirst, streams);
27 }
28
29 AndSearchResults(IndexOther index, String[] words, boolean grouped)
30 throws FTIException, DatabaseException {
31 this.grouped = grouped;
32 streams = new TextStream[words.length];
33 for (int w = 0; w < words.length; ++w)
34 streams[w] = new TextStream(index, words[w]);
35
36 if (grouped) {
37 TextStream[] s = new TextStream[streams.length];
38 System.arraycopy(streams, 0, s, 0, streams.length);
39 occurrences = new GroupTextSearchResults(s);
40 } else
41 occurrences = new OrTextSearchResults(streams);
42
43 construct();
44 }
45
46 AndSearchResults(SearchResults[] streams) throws FTIException {
47 this.grouped = false;
48 this.streams = streams;
49 construct();
50 occurrences = new OrTextSearchResults(streams);
51 }
52
53 public int frequency() {
54 return frequency;
55 }
56
57 public void gotoText(long textIdP) throws DatabaseException {
58 if (streams.length == 0)
59 this.textID = -1;
60 else
61 do {
62 int lastW = -1;
63 for (int w = 0; w < streams.length;) {
64 if (w == lastW)
65 ++w;
66 else {
67 SearchResults stream = streams[w];
68
69 stream.gotoText(textIdP);
70
71 if (stream.currentTextID() == -1) {
72 this.textID = -1;
73 return;
74 }
75
76 if (stream.currentTextID() != textIdP) {
77 textIdP = stream.currentTextID();
78 lastW = w;
79 w = 0;
80 } else
81 ++w;
82 }
83 }
84
85 this.textID = textIdP++;
86 occurrences.init();
87 } while (grouped && occurrences.currentWordIndex() == -1);
88 }
89
90 public int hitWordsCount() {
91 return occurrences.hitWordsCount();
92 }
93
94 public void init() {
95 occurrences.init();
96 }
97
98 public long currentTextID() {
99 return textID;
100 }
101
102 public void skipToNextHit() {
103 occurrences.skipToNextHit();
104 }
105
106 public void skipToWordIndex(int wordIndex) {
107 occurrences.skipToWordIndex(wordIndex);
108 }
109
110 public int currentWordIndex() {
111 return occurrences.currentWordIndex();
112 }
113
114 public int currentOffset() {
115 return occurrences.currentOffset();
116 }
117
118 public void close() {
119 for (int i = 0; i < streams.length; ++i)
120 streams[i].close();
121 occurrences.close();
122 }
123 }