package org.basex.index; import static org.basex.core.Text.*; import org.basex.core.Prop; import org.basex.data.Data; import org.basex.util.Token; import org.basex.util.TokenBuilder; /** * This class assembles some index statistics. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public final class IndexStats { /** Number of entries to print. */ private final int max; /** Minimum occurrences. */ private final int[] occMin; /** Maximum occurrences. */ private final int[] occMax; /** Minimal occurring tokens. */ private final byte[][] txtMin; /** Maximal occurring tokens. */ private final byte[][] txtMax; /** Number of index entries. */ private int size; /** Current number of occurrence. */ private int co; /** * Default constructor. * @param d data reference */ public IndexStats(final Data d) { max = d.meta.prop.num(Prop.MAXSTAT); occMin = new int[max]; occMax = new int[max]; txtMin = new byte[max][]; txtMax = new byte[max][]; for(int o = 0; o < txtMin.length; ++o) { txtMin[o] = Token.EMPTY; txtMax[o] = Token.EMPTY; occMin[o] = Integer.MAX_VALUE; } } /** * Checks if the specified number of occurrence will be remembered. * @param oc number of occurrences * @return result of check */ public boolean adding(final int oc) { co = oc; ++size; return oc > occMax[max - 1] || oc < occMin[max - 1]; } /** * Adds the specified token. * @param tx token to be added */ public void add(final byte[] tx) { final boolean dsc = co > occMax[max - 1]; final byte[][] txt = dsc ? txtMax : txtMin; final int[] ocs = dsc ? occMax : occMin; for(int a = max - 1; a >= 0; a--) { if(a == 0 || dsc && co < ocs[a - 1] || !dsc && co > ocs[a - 1]) { txt[a] = tx; ocs[a] = co; break; } txt[a] = txt[a - 1]; ocs[a] = ocs[a - 1]; } } /** * Prints the list to the specified token builder. * @param tb token builder reference */ public void print(final TokenBuilder tb) { tb.add(LI_ENTRIES + size + NL); int m = 0; int c = 0; for(int o = 0; o < max; ++o) { int tl = txtMin[o].length; if(tl == 0) ++c; else if(m < tl) m = tl; tl = txtMax[o].length; if(tl == 0) ++c; else if(m < tl) m = tl; } print(tb, txtMax, occMax, m + 2); if(c == 0) tb.add(" " + DOTS + NL); print(tb, txtMin, occMin, m + 2); } /** * Internal method for printing the list. * @param tb token builder reference * @param txt text reference * @param ocs occurrences * @param len text length */ private static void print(final TokenBuilder tb, final byte[][] txt, final int[] ocs, final int len) { for(int o = 0; o < ocs.length; ++o) { if(txt[o].length == 0) continue; tb.add(" ").add(txt[o]); for(int j = 0; j < len - txt[o].length; ++j) tb.add(' '); tb.addLong(ocs[o]).add('x').add(NL); } } }