2
* @(#)HitStore.java 1.7 06/10/30
4
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7
* This code is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License version 2 only, as
9
* published by the Free Software Foundation. Sun designates this
10
* particular file as subject to the "Classpath" exception as provided
11
* by Sun in the LICENSE file that accompanied this code.
13
* This code is distributed in the hope that it will be useful, but WITHOUT
14
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16
* version 2 for more details (a copy is included in the LICENSE file that
17
* accompanied this code).
19
* You should have received a copy of the GNU General Public License version
20
* 2 along with this work; if not, write to the Free Software Foundation,
21
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
24
* CA 95054 USA or visit www.sun.com if you need additional information or
30
* @author Jacek R. Ambroziak
31
* @group Sun Microsystems Laboratories
34
package com.sun.java.help.search;
36
import java.util.Vector;
40
private int _free = 0;
42
private QueryHit[] _array;
43
private int _hitCount = 0;
44
private double _divider = 0.0;
45
private double _min = 10000000.0;
46
private double _max = 0.0;
47
private HitStoreNode[] _children = new HitStoreNode[2]; // left & right
48
private int _index = 0;
50
public HitStoreNode(int size) {
51
_array = new QueryHit[_size = size];
54
public QueryHit getNextHit() {
55
return _index < _free ? _array[_index++] : null;
58
private void fastAdd(QueryHit hit)
61
_divider += hit.getScore();
62
if (hit.getScore() > _max)
63
_max = hit.getScore();
64
if (hit.getScore() < _min)
65
_min = hit.getScore();
66
_array[_free++] = hit;
69
public boolean add(QueryHit hit)
78
else if (_min != _max)
82
_children[hit.getScore() > _divider ? 1 : 0].fastAdd(hit);
87
QueryHit[] newArray = new QueryHit[_size *= 2];
88
System.arraycopy(_array, 0, newArray, 0, _free);
97
return _children[hit.getScore() > _divider ? 1 : 0].add(hit);
103
_children[0] = new HitStoreNode(_size);
104
_children[1] = new HitStoreNode(_size);
105
_divider /= _hitCount; // becomes average
106
for (int i = 0; i < _free; i++)
107
_children[_array[i].getScore() > _divider ? 1 : 0].fastAdd(_array[i]);
108
_array = null; // becomes internal
110
public int getCount() {
113
public double getDivider() {
116
public HitStoreNode getLChild() {
119
public HitStoreNode getRChild() {
122
public void setLChild(HitStoreNode node) {
125
public void setRChild(HitStoreNode node) {
128
public void decrementCount(int delta) {
131
public boolean isLeaf() {
132
return _array != null;
136
quicksort(0, _free - 1);
139
public void gatherLeaves(Vector vector)
142
vector.addElement(this);
145
getLChild().gatherLeaves(vector);
146
getRChild().gatherLeaves(vector);
150
// part of quicksearch
151
private int partition(int p, int r)
153
QueryHit x = _array[p];
154
int i = p - 1, j = r + 1;
157
while (x.betterThan(_array[--j]))
159
while (_array[++i].betterThan(x))
163
QueryHit t = _array[i];
164
_array[i] = _array[j];
172
private void quicksort(int p, int r)
176
int q = partition(p, r);
186
private static final int ArraySize = 128;
187
private static final int DefaultLimit = 300;
189
private HitStoreNode _root = new HitStoreNode(ArraySize);
191
private double _standard;
192
private Vector _leaves = null;
193
private HitStoreNode _current = null;
195
public HitStore(double initialStandard) {
196
this(initialStandard, DefaultLimit);
199
public HitStore(double initialStandard, int limit)
202
_standard = initialStandard;
205
public void addQueryHit(QueryHit hit) {
210
private HitStoreNode getNextNode()
212
if (_leaves.size() > 0)
214
HitStoreNode node = (HitStoreNode)_leaves.firstElement();
215
_leaves.removeElementAt(0);
223
public QueryHit firstBestQueryHit()
225
_leaves = new Vector();
226
_root.gatherLeaves(_leaves);
227
_current = getNextNode();
228
return _current.getNextHit();
231
public QueryHit nextBestQueryHit()
233
QueryHit result = _current.getNextHit();
236
else if ((_current = getNextNode()) != null)
237
return _current.getNextHit();
242
double getCurrentStandard() {
248
if (_root.getCount() > _limit)
251
HitStoreNode ptr = _root;
252
// find rightmost internal
253
while (!ptr.getRChild().isLeaf())
254
ptr = ptr.getRChild();
256
_standard = ptr.getDivider();
259
_root = ptr.getLChild();
262
int count = ptr.getRChild().getCount();
263
HitStoreNode ptr2 = _root;
264
while (ptr2.getRChild() != ptr)
266
ptr2.decrementCount(count);
267
ptr2 = ptr2.getRChild();
269
ptr2.setRChild(ptr.getLChild());