org.crosswire.jsword.passage
Class PassageTally

java.lang.Object
  extended by org.crosswire.jsword.passage.AbstractPassage
      extended by org.crosswire.jsword.passage.PassageTally
All Implemented Interfaces:
Serializable, Cloneable, Comparable, Key, Passage

public class PassageTally
extends AbstractPassage

Similar to a Passage, but that stores a ranking for each of the Verses that it contains.

Currently there is no well defined spec for what the rank of a verse means - it is just an int. Since this number is expoed in 2 places (getNameAndTally() and getTallyFor()) we should specify what the numbers mean. Trouble is most tallies come from searches where the numbers only have relative meaning.

This class exactly implements the Passage interface when the ordering is set to ORDER_BIBLICAL, however an additional setting of ORDER_TALLY sorts the verses by the rank in this tally.

Calling tally.add(Gen 1:1); tally.add(Gen 1:1); is redundant for a Passage however a PassageTally will increase the rank of Gen 1:1, there are additional methods unAdd() and unAddAll() that do the reverse, of decreasing the rank of the specified verse(s).

The point is to allow a search for "God loves us, and gave Jesus to die to save us" to correctly identify John 3:16. So we are using fuzzy matching big style, but I think this will be very useful.

How should we rank VerseRanges? We could use a sum of the ranks of the verses in a range or the maximum value of a range. The former would seem to be more mathematically correct, but I think that the latter is better because: the concept of max value is preserved, because a wide blurred match is generally not as good as a sharply defined one.

Should we be going for a PassageTallyFactory type approach? Of the 3 implentations of Passage, The RangedPassage does not make sense here, and a PassageTally will not have the range of uses that a Passage has, so I think there is more likely to be a correct answer. So right now the answer is no.

Memory considerations: The BitSet approach will always use a int[31000] = 128k of memory.
The Distinct approach will be n * int[4] where n is the number of verses stored. I expect most searches to have at least n=1000. Also 128k
Given this, (A Distinct style PassageTally will usually use more memory than a BitSet sytle PassageTally) And the intuative result that the BitSet will be faster, I'm going to start by implementing the latter only.

To think about - I've upped the MAX_TALLY to 20000 to help the new mapper program. I'm not sure why it was originally 100?

LATER(joe): Specify how passage ranks work.

Distribution Licence:
JSword is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
The License is available on the internet here, or by writing to: Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
The copyright to this program is held by it's authors.

Version:
$Id: PassageTally.java,v 1.32 2005/03/19 18:44:58 dmsmith Exp $
Author:
Joe Walker [joe at eireneh dot com]
See Also:
Licence, Serialized Form

Nested Class Summary
private static class PassageTally.OrderedVerseIterator
          Iterate over the Verses in order of their rank in the tally
private static class PassageTally.OrderedVerseRangeIterator
          Iterate over the Ranges in order of their rank in the tally
private static class PassageTally.TalliedVerse
          JDK: Hack to make this work with J2SE 1.1 as well as J2SE 1.2 This compared 2 Integers
private static class PassageTally.TalliedVerseRange
          Hack to make this work with JDK1.1 as well as JDK1.2 This compared 2 Integers
private  class PassageTally.VerseIterator
          Iterate over the Verses in normal verse order
 
Nested classes/interfaces inherited from class org.crosswire.jsword.passage.AbstractPassage
AbstractPassage.VerseRangeIterator
 
Field Summary
protected  int[] board
          The tallyboard itself
private static Logger log
          The log stream
private  int max
          The maximum tally possible
static int MAX_TALLY
          The highest tally possible
private  int order
          The maximum tally possible
static int ORDER_BIBLICAL
          Sort in Biblical order
static int ORDER_TALLY
          Sort in tally rank order
private static long serialVersionUID
          Serialization ID
 
Fields inherited from class org.crosswire.jsword.passage.AbstractPassage
BITWISE, DISTINCT, listeners, METHOD_COUNT, originalName, RANGED, REF_ALLOWED_DELIMS, REF_OSIS_DELIM, REF_PREF_DELIM, skipNormalization, suppressEvents
 
Constructor Summary
PassageTally()
          Create an empty PassageTally
PassageTally(String refs)
          Create a Verse from a human readable string.
 
Method Summary
 void add(VerseBase that)
          Add/Increment this verses in the rankings
 void add(VerseBase that, int count)
          DONT USE THIS.
 void addAll(Key that)
          Add/Increment these verses in the rankings
private  void alterVerseBase(VerseBase that, int tally)
          Increment/Decrement this verses in the rankings
 void blur(int verses, RestrictionType restrict)
          Widen the range of the verses in this list.
 void clear()
          Removes all of the Verses from this Passage.
 Object clone()
          Get a copy of ourselves.
 boolean contains(VerseBase that)
          Does this tally contain all the specified verses?
 void flatten()
          Take the verses in the tally and give them all and equal rank of 1.
 int getIndexOf(Verse verse)
          What is the index of the give verse in the current ordering scheme
 String getName()
          A Human readable version of the PassageTally.
 String getName(int max_count)
          A Human readable version of the verse list.
 String getNameAndTally()
          A Human readable version of the PassageTally.
 String getNameAndTally(int max_count)
          A Human readable version of the PassageTally.
 int getOrdering()
          Get how we sort the verses we output.
 int getTallyOf(Verse verse)
          The ranking given to a specific verse
private  void increment(int ord, int tally)
          Increment a verse by an amount
private  void incrementMax(int tally)
          Increment a verse by an amount
 Iterator iterator()
          Iterate through the verse elements in the current sort order
private  void kill(int ord)
          Wipe the rank of the given verse to zero
 Iterator rangeIterator(RestrictionType restrict)
          Iterate through the range elements in the current sort order
 void remove(VerseBase that)
          Remove these verses from the rankings, ie, set their rank to zero.
 void removeAll(Key key)
          Remove/Decrement these verses in the rankings
private  void resetMax()
          Sometimes we end up not knowing what the max is - this makes sure we know accurately
 void setOrdering(int order)
          Set how we sort the verses we output.
 String toString()
          Simply bounce to getName() to help String concatenation.
 Passage trimVerses(int count)
          Ensures that there are a maximum of count Verses in this Passage.
 void unAdd(VerseBase that)
          Remove/Decrement this verses in the rankings
 void unAddAll(Passage that)
          Remove/Decrement these verses in the rankings
 
Methods inherited from class org.crosswire.jsword.passage.AbstractPassage
addPassageListener, addVerses, booksInPassage, canHaveChildren, chaptersInPassage, compareTo, contains, containsAll, countRanges, countVerses, equals, fireContentsChanged, fireIntervalAdded, fireIntervalRemoved, get, getChildCount, getOSISName, getOverview, getParent, getRangeAt, getVerseAt, hashCode, indexOf, isEmpty, lowerEventSuppresionAndTest, lowerNormalizeProtection, normalize, optimizeReads, optimizeWrites, raiseEventSuppresion, raiseNormalizeProtection, readDescription, readObjectSupport, removePassageListener, retainAll, setParent, toVerseArray, toVerseRange, trimRanges, versesInPassage, writeDescription, writeObjectSupport
 
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

ORDER_BIBLICAL

public static final int ORDER_BIBLICAL
Sort in Biblical order

See Also:
Constant Field Values

ORDER_TALLY

public static final int ORDER_TALLY
Sort in tally rank order

See Also:
Constant Field Values

MAX_TALLY

public static final int MAX_TALLY
The highest tally possible

See Also:
Constant Field Values

board

protected int[] board
The tallyboard itself


max

private int max
The maximum tally possible


order

private int order
The maximum tally possible


log

private static final Logger log
The log stream


serialVersionUID

private static final long serialVersionUID
Serialization ID

See Also:
Constant Field Values
Constructor Detail

PassageTally

public PassageTally()
Create an empty PassageTally


PassageTally

public PassageTally(String refs)
             throws NoSuchVerseException
Create a Verse from a human readable string. The opposite of toString()

Parameters:
refs - The text to interpret
Throws:
NoSuchVerseException - If refs is invalid
Method Detail

setOrdering

public void setOrdering(int order)
Set how we sort the verses we output. The options are:

Parameters:
order - the sort order

getOrdering

public int getOrdering()
Get how we sort the verses we output.

Returns:
the sort order

clone

public Object clone()
Get a copy of ourselves.

Specified by:
clone in interface Passage
Overrides:
clone in class AbstractPassage
Returns:
A complete copy of ourselves

toString

public String toString()
Simply bounce to getName() to help String concatenation.

Overrides:
toString in class AbstractPassage
Returns:
a String containing a description of the verses

getName

public String getName()
A Human readable version of the PassageTally. Uses short books names, and the shortest possible rendering eg "Mat 3:1-4"

Specified by:
getName in interface Key
Overrides:
getName in class AbstractPassage
Returns:
a String containing a description of the verses

getName

public String getName(int max_count)
A Human readable version of the verse list. Uses short books names, and the shortest possible rendering eg "Mat 3:1-4, 6"

Parameters:
max_count - The number of matches to return, 0 gives all matches
Returns:
a String containing a description of the verses

getNameAndTally

public String getNameAndTally()
A Human readable version of the PassageTally. Uses short books names, and the shortest possible rendering eg "Mat 3:1-4"

Returns:
a String containing a description of the verses

getNameAndTally

public String getNameAndTally(int max_count)
A Human readable version of the PassageTally. Uses short books names, and the shortest possible rendering eg "Mat 3:1-4"

Parameters:
max_count - The number of matches to return, 0 gives all matches
Returns:
a String containing a description of the verses

iterator

public Iterator iterator()
Iterate through the verse elements in the current sort order

Specified by:
iterator in interface Key
Overrides:
iterator in class AbstractPassage
Returns:
A verse Iterator

rangeIterator

public Iterator rangeIterator(RestrictionType restrict)
Iterate through the range elements in the current sort order

Specified by:
rangeIterator in interface Passage
Overrides:
rangeIterator in class AbstractPassage
Parameters:
restrict - Do we break ranges over chapters
Returns:
A range Iterator

contains

public boolean contains(VerseBase that)
Does this tally contain all the specified verses?

Parameters:
that - The verses to test for
Returns:
true if all the verses exist in this tally

getTallyOf

public int getTallyOf(Verse verse)
The ranking given to a specific verse

Parameters:
verse - The verse to get the ranking of
Returns:
The rank of the verse in question

getIndexOf

public int getIndexOf(Verse verse)
What is the index of the give verse in the current ordering scheme

Parameters:
verse - The verse to get the index of
Returns:
The index of the verse or -1 if the verse was not found

add

public void add(VerseBase that)
Add/Increment this verses in the rankings

Parameters:
that - The verses to add/increment

add

public void add(VerseBase that,
                int count)
DONT USE THIS. It makes public something of the ratings scheme which is not generally recommended. This method is likely to be removed at a moments notice, and it only here to keep Mapper happy. Add/Increment this verses in the rankings

Parameters:
that - The verses to add/increment
count - The amount to increment by

unAdd

public void unAdd(VerseBase that)
Remove/Decrement this verses in the rankings

Parameters:
that - The verses to remove/decrement

remove

public void remove(VerseBase that)
Remove these verses from the rankings, ie, set their rank to zero.

Parameters:
that - The verses to remove/decrement

addAll

public void addAll(Key that)
Add/Increment these verses in the rankings

Specified by:
addAll in interface Key
Overrides:
addAll in class AbstractPassage
Parameters:
that - The verses to add/increment

unAddAll

public void unAddAll(Passage that)
Remove/Decrement these verses in the rankings

Parameters:
that - The verses to remove/decrement

removeAll

public void removeAll(Key key)
Remove/Decrement these verses in the rankings

Specified by:
removeAll in interface Key
Overrides:
removeAll in class AbstractPassage
Parameters:
key - The verses to remove/decrement

clear

public void clear()
Removes all of the Verses from this Passage.

Specified by:
clear in interface Key
Overrides:
clear in class AbstractPassage

trimVerses

public Passage trimVerses(int count)
Ensures that there are a maximum of count Verses in this Passage. If there were more than count Verses then a new Passage is created containing the Verses from count + 1 onwards. If there was not greater than count in the Passage, then the passage remains unchanged, and null is returned.

Specified by:
trimVerses in interface Passage
Overrides:
trimVerses in class AbstractPassage
Parameters:
count - The maximum number of Verses to allow in this collection
Returns:
A new Passage conatining the remaining verses or null
See Also:
Verse

flatten

public void flatten()
Take the verses in the tally and give them all and equal rank of 1. After this method has executed then both sorting methods for a.


blur

public void blur(int verses,
                 RestrictionType restrict)
Widen the range of the verses in this list. This is primarily for "find x within n verses of y" type applications.

Specified by:
blur in interface Key
Overrides:
blur in class AbstractPassage
Parameters:
verses - The number of verses to widen by
restrict - How should we restrict the blurring?
See Also:
Passage

resetMax

private void resetMax()
Sometimes we end up not knowing what the max is - this makes sure we know accurately


alterVerseBase

private void alterVerseBase(VerseBase that,
                            int tally)
Increment/Decrement this verses in the rankings

Parameters:
that - The verses to add/increment
tally - The amount to increment/decrement by

increment

private final void increment(int ord,
                             int tally)
Increment a verse by an amount

Parameters:
ord - The verse to increment
tally - The amount to inrease by

incrementMax

private final void incrementMax(int tally)
Increment a verse by an amount

Parameters:
tally - The amount to inrease by

kill

private final void kill(int ord)
Wipe the rank of the given verse to zero

Parameters:
ord - The verse to increment

Copyright ? 2003-2004