package org.basex.data;
import java.util.Arrays;
import java.util.Iterator;
import org.basex.util.Array;
import org.basex.util.Util;
/**
* AllMatches full-text container,
* referencing several {@link FTMatch} instances.
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
*/
public final class FTMatches implements Iterable<FTMatch> {
/** Full-text matches. */
public FTMatch[] match = {};
/** Number of entries. */
public int size;
/** Current number of tokens. */
public int sTokenNum;
/**
* Constructor.
* @param s sets the token number
*/
public FTMatches(final int s) {
reset(s);
}
/**
* Resets the match counter.
* @param s sets the token number
*/
public void reset(final int s) {
sTokenNum = s;
size = 0;
}
/**
* Adds a match entry.
* @param p position
*/
public void or(final int p) {
or(p, p);
}
/**
* Adds a match entry.
* @param s start position
* @param e end position
*/
public void or(final int s, final int e) {
add(new FTMatch().add(new FTStringMatch(s, e, sTokenNum)));
}
/**
* Adds a match entry.
* @param s start position
* @param e end position
*/
public void and(final int s, final int e) {
final FTStringMatch sm = new FTStringMatch(s, e, sTokenNum);
for(final FTMatch m : this) m.add(sm);
}
/**
* Adds a match entry.
* @param m match to be added
*/
public void add(final FTMatch m) {
if(size == match.length) match = size == 0 ?
new FTMatch[1] : Arrays.copyOf(match, size << 1);
match[size++] = m;
}
/**
* Removes the specified match.
* @param i match offset
*/
public void delete(final int i) {
Array.move(match, i + 1, -1, --size - i);
}
/**
* Checks if at least one of the matches contains only includes.
* @return result of check
*/
public boolean matches() {
for(final FTMatch m : this) if(m.match()) return true;
return false;
}
/**
* Combines two matches as phrase.
* @param all second match list
* @param dis word distance
* @return true if matches are left
*/
public boolean phrase(final FTMatches all, final int dis) {
int a = 0, b = 0, c = 0;
while(a < size && b < all.size) {
final int e = all.match[b].match[0].s;
final int d = e - match[a].match[0].e - dis;
if(d == 0) {
match[c] = match[a];
match[c++].match[0].e = e;
}
if(d >= 0) ++a;
if(d <= 0) ++b;
}
size = c;
return size != 0;
}
@Override
public Iterator<FTMatch> iterator() {
return new Iterator<FTMatch>() {
private int c = -1;
@Override
public boolean hasNext() { return ++c < size; }
@Override
public FTMatch next() { return match[c]; }
@Override
public void remove() { Util.notexpected(); }
};
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append(Util.name(this) + '[' + sTokenNum + ']');
for(final FTMatch m : this) sb.append("\n ").append(m);
return sb.toString();
}
}