// Path: src/main/java/de/danielbasedow/prospecter/core/query/QueryManager.java
// public class QueryManager {
//     protected final TIntIntHashMap bitCounts = new TIntIntHashMap();
//     protected final TIntObjectHashMap<QueryNegativeCounter> negativeCounts = new TIntObjectHashMap<QueryNegativeCounter>();
// 
//     public void addQuery(Query query) {
//         bitCounts.put(query.getQueryId(), query.getBits());
//         if (query.hasNegatives()) {
//             negativeCounts.put(query.getQueryId(), query.getNegativeMask());
//         }
// 
//     }
// 
//     public BitSet getMask(int queryId) {
//         BitSet set = new BitSet();
//         set.set(0, bitCounts.get(queryId), true);
//         return set;
//     }
// 
//     public void deleteQuery(int queryId) {
//         bitCounts.remove(queryId);
//     }
// 
//     public QueryNegativeCounter getQueryNegativeCounter(int queryId) {
//         return negativeCounts.get(queryId);
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/query/QueryNegativeCounter.java
// public class QueryNegativeCounter {
//     private final TIntByteMap bitCounts = new TIntByteHashMap();
// 
//     public void add(int bit) {
//         bitCounts.adjustOrPutValue(bit, (byte) 1, (byte) 1);
//     }
// 
//     public int size() {
//         return bitCounts.size();
//     }
// 
//     public byte getCountAtBit(int bit) {
//         return bitCounts.get(bit);
//     }
// 
//     public int[] getBitPositionsToSet(QueryNegativeCounter actualMatched) {
//         TIntList results = new TIntArrayList();
// 
//         for (int bitPosition : bitCounts.keys()) {
//             if (bitCounts.get(bitPosition) > actualMatched.getCountAtBit(bitPosition)) {
//                 results.add(bitPosition);
//             }
//         }
// 
//         return results.toArray();
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/query/QueryPosting.java
// public class QueryPosting {
//     public static final int QUERY_ID_INDEX = 0;
//     public static final int QUERY_BIT_INDEX = 1;
//     public static final int QUERY_NOT_INDEX = 2;
// 
//     private final int queryId;
//     private final short queryBit;
// 
//     public QueryPosting(int queryId, short queryBit) {
//         this.queryId = queryId;
//         this.queryBit = queryBit;
//     }
// 
//     public int getQueryId() {
//         return queryId;
//     }
// 
//     public short getQueryBit() {
//         return queryBit;
//     }
// 
//     public long getPackedPosting() {
//         return pack(queryId, queryBit, false);
//     }
// 
//     public static long pack(int queryId, int queryBit, boolean notFlag) {
//         int not = notFlag ? 1 : 0;
// 
//         return (((long) queryId) << 32) | ((queryBit << 1 ) & 0xfffffffeL) | ((long) not & 0x00000001L);
//     }
// 
//     public static int[] unpack(long posting) {
//         return new int[]{
//                 (int) (posting >> 32),
//                 (int) ((posting) & 0xfffffffel) >> 1,
//                 (int) ((posting) & 0x00000001l)
//         };
//     }
// }


import de.danielbasedow.prospecter.core.query.QueryManager;
import de.danielbasedow.prospecter.core.query.QueryNegativeCounter;
import de.danielbasedow.prospecter.core.query.QueryPosting;
import gnu.trove.list.TLongList;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.procedure.TIntObjectProcedure;
import gnu.trove.procedure.TLongProcedure;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
package de.danielbasedow.prospecter.core;



/**
 * Tracks hits across multiple index fields and applies the bit from the QueryPostings.
 */
public class Matcher {
    protected final TIntObjectHashMap<BitSet> hits = new TIntObjectHashMap<BitSet>();
    protected final TIntObjectHashMap<QueryNegativeCounter> negativeHits = new TIntObjectHashMap<QueryNegativeCounter>();

// Path: src/main/java/de/danielbasedow/prospecter/core/query/QueryManager.java
// public class QueryManager {
//     protected final TIntIntHashMap bitCounts = new TIntIntHashMap();
//     protected final TIntObjectHashMap<QueryNegativeCounter> negativeCounts = new TIntObjectHashMap<QueryNegativeCounter>();
// 
//     public void addQuery(Query query) {
//         bitCounts.put(query.getQueryId(), query.getBits());
//         if (query.hasNegatives()) {
//             negativeCounts.put(query.getQueryId(), query.getNegativeMask());
//         }
// 
//     }
// 
//     public BitSet getMask(int queryId) {
//         BitSet set = new BitSet();
//         set.set(0, bitCounts.get(queryId), true);
//         return set;
//     }
// 
//     public void deleteQuery(int queryId) {
//         bitCounts.remove(queryId);
//     }
// 
//     public QueryNegativeCounter getQueryNegativeCounter(int queryId) {
//         return negativeCounts.get(queryId);
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/query/QueryNegativeCounter.java
// public class QueryNegativeCounter {
//     private final TIntByteMap bitCounts = new TIntByteHashMap();
// 
//     public void add(int bit) {
//         bitCounts.adjustOrPutValue(bit, (byte) 1, (byte) 1);
//     }
// 
//     public int size() {
//         return bitCounts.size();
//     }
// 
//     public byte getCountAtBit(int bit) {
//         return bitCounts.get(bit);
//     }
// 
//     public int[] getBitPositionsToSet(QueryNegativeCounter actualMatched) {
//         TIntList results = new TIntArrayList();
// 
//         for (int bitPosition : bitCounts.keys()) {
//             if (bitCounts.get(bitPosition) > actualMatched.getCountAtBit(bitPosition)) {
//                 results.add(bitPosition);
//             }
//         }
// 
//         return results.toArray();
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/query/QueryPosting.java
// public class QueryPosting {
//     public static final int QUERY_ID_INDEX = 0;
//     public static final int QUERY_BIT_INDEX = 1;
//     public static final int QUERY_NOT_INDEX = 2;
// 
//     private final int queryId;
//     private final short queryBit;
// 
//     public QueryPosting(int queryId, short queryBit) {
//         this.queryId = queryId;
//         this.queryBit = queryBit;
//     }
// 
//     public int getQueryId() {
//         return queryId;
//     }
// 
//     public short getQueryBit() {
//         return queryBit;
//     }
// 
//     public long getPackedPosting() {
//         return pack(queryId, queryBit, false);
//     }
// 
//     public static long pack(int queryId, int queryBit, boolean notFlag) {
//         int not = notFlag ? 1 : 0;
// 
//         return (((long) queryId) << 32) | ((queryBit << 1 ) & 0xfffffffeL) | ((long) not & 0x00000001L);
//     }
// 
//     public static int[] unpack(long posting) {
//         return new int[]{
//                 (int) (posting >> 32),
//                 (int) ((posting) & 0xfffffffel) >> 1,
//                 (int) ((posting) & 0x00000001l)
//         };
//     }
// }


// Path: src/main/java/de/danielbasedow/prospecter/core/Matcher.java
import de.danielbasedow.prospecter.core.query.QueryManager;
import de.danielbasedow.prospecter.core.query.QueryNegativeCounter;
import de.danielbasedow.prospecter.core.query.QueryPosting;
import gnu.trove.list.TLongList;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.procedure.TIntObjectProcedure;
import gnu.trove.procedure.TLongProcedure;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;

package de.danielbasedow.prospecter.core;



/**
 * Tracks hits across multiple index fields and applies the bit from the QueryPostings.
 */
public class Matcher {
    protected final TIntObjectHashMap<BitSet> hits = new TIntObjectHashMap<BitSet>();
    protected final TIntObjectHashMap<QueryNegativeCounter> negativeHits = new TIntObjectHashMap<QueryNegativeCounter>();

    protected final QueryManager queryManager;