@Override Leaf<K, V> put(K key, int hash, int hashBits, V value, MutableValueInt newValue) { assert hashBits <= 0 : hashBits; int slot = -1; for (int i = 0; i < keys.length; i++) { if (key.equals(keys[i])) { slot = i; break; } } final K[] keys2; final V[] values2; if (slot < 0) { keys2 = appendElement(keys, key); values2 = appendElement(values, value); newValue.value = 1; } else { keys2 = replace(keys, slot, key); values2 = replace(values, slot, value); } return new Leaf<>(keys2, values2); }
private InnerNode<K, V> putExisting(K key, int hash, int hashBits, int slot, V value, MutableValueInt newValue) { final K[] keys2 = Arrays.copyOf(keys, keys.length); final Object[] subNodes2 = Arrays.copyOf(subNodes, subNodes.length); final Object previousValue = subNodes2[slot]; if (previousValue instanceof Node) { // insert recursively assert keys[slot] == null; subNodes2[slot] = ((Node<K, V>) previousValue).put(key, hash, hashBits, value, newValue); } else if (keys[slot].equals(key)) { // replace the existing entry subNodes2[slot] = value; } else { // hash collision final K previousKey = keys[slot]; final int previousHash = previousKey.hashCode() >>> (TOTAL_HASH_BITS - hashBits); Node<K, V> subNode = newSubNode(hashBits); subNode = subNode.put(previousKey, previousHash, hashBits, (V) previousValue, newValue); subNode = subNode.put(key, hash, hashBits, value, newValue); keys2[slot] = null; subNodes2[slot] = subNode; } return new InnerNode<>(mask, keys2, subNodes2); }
@Override public ValueFiller getValueFiller() { return new ValueFiller() { private final MutableValueInt mval = new MutableValueInt(); @Override public MutableValue getValue() { return mval; } @Override public void fillValue(int doc) { mval.value = intVal(doc); mval.exists = exists(doc); } }; }
@Override InnerNode<K, V> put(K key, int hash, int hashBits, V value, MutableValueInt newValue) { final int hash6 = hash & HASH_MASK; final int slot = slot(hash6); if (exists(hash6)) { hash >>>= HASH_BITS; hashBits -= HASH_BITS; return putExisting(key, hash, hashBits, slot, value, newValue); } else { newValue.value = 1; return putNew(key, hash6, slot, value); } }
/** * Associate <code>key</code> with <code>value</code> and return a new copy * of the hash table. The current hash table is not modified. */ public CopyOnWriteHashMap<K, V> copyAndPut(K key, V value) { if (key == null) { throw new IllegalArgumentException("null keys are not supported"); } if (value == null) { throw new IllegalArgumentException("null values are not supported"); } final int hash = key.hashCode(); final MutableValueInt newValue = new MutableValueInt(); final InnerNode<K, V> newRoot = root.put(key, hash, TOTAL_HASH_BITS, value, newValue); final int newSize = size + newValue.value; return new CopyOnWriteHashMap<>(newRoot, newSize); }
/** * Associate <code>key</code> with <code>value</code> and return a new copy * of the hash table. The current hash table is not modified. */ public CopyOnWriteHashMap<K, V> copyAndPut(K key, V value) { Preconditions.checkArgument(key != null, "null keys are not supported"); Preconditions.checkArgument(value != null, "null values are not supported"); final int hash = key.hashCode(); final MutableValueInt newValue = new MutableValueInt(); final InnerNode<K, V> newRoot = root.put(key, hash, TOTAL_HASH_BITS, value, newValue); final int newSize = size + newValue.value; return new CopyOnWriteHashMap<>(newRoot, newSize); }
private List<TermIDF> getResults(String fieldName, CharArrayMap<MutableValueInt> map, int numResults) { TFIDFPriorityQueue queue = new TFIDFPriorityQueue(numResults); IDFIndexCalc idfCalc = new IDFIndexCalc(searcher.getIndexReader()); int tf = -1; double idf = -1.0; int minTf = minTermFreq; String text = null; //make more efficient // Term reusableTerm = new Term(fieldName, ""); for (Map.Entry<Object, MutableValueInt> entry : map.entrySet()) { tf = entry.getValue().value; if (tf < minTf) continue; text = new String((char[]) entry.getKey()); // calculate idf for potential phrase try { idf = idfCalc.singleTermIDF(new Term(fieldName, text)); } catch (IOException e) { throw new RuntimeException("Error trying to calculate IDF: " + e.getMessage()); } int estimatedDF = (int) Math.max(1, Math.round(idfCalc.unIDF(idf))); TermIDF r = new TermIDF(text, estimatedDF, tf, idf); queue.insertWithOverflow(r); } List<TermIDF> results = new LinkedList<>(); while (queue.size() > 0) { results.add(0, queue.pop()); } return results; }
@Override public List<TermDFTF> getResults() { List<TermDFTF> list = new ArrayList<>(); for (Map.Entry<String, MutableValueInt> entry : df.entrySet()) { String key = entry.getKey(); int docFreq = entry.getValue().value; MutableValueInt mutTF = tf.get(key); int termFreq = (mutTF == null) ? 0 : mutTF.value; list.add(new TermDFTF(key, docFreq, termFreq)); } Collections.sort(list); //if list is short enough, return now if (list.size() <= numResults) { return list; } //copy over only the required results List<TermDFTF> ret = new ArrayList<>(); int i = 0; for (TermDFTF t : list) { if (i++ >= numResults) { break; } ret.add(t); } return ret; }
/** * can throw RuntimeException if there is an IOException * while calculating the IDFs */ public List<TermIDF> getResults() { TFIDFPriorityQueue queue = new TFIDFPriorityQueue(numResults); int tf = -1; double idf = -1.0; int minTf = minTermFreq; String text = ""; Term reusableTerm = new Term(getFieldName(), ""); for (Map.Entry<String, MutableValueInt> entry : tfs.entrySet()) { tf = entry.getValue().value; if (tf < minTf) continue; text = entry.getKey(); // calculate idf for potential phrase double[] stats; try { stats = idfCalc.multiTermIDF(text, reusableTerm); } catch (IOException e) { throw new RuntimeException("Error trying to calculate IDF: " + e.getMessage()); } idf = stats[0]; int estimatedDF = (int) Math.max(1, Math.round(idfCalc.unIDF(idf))); TermIDF r = new TermIDF(text, estimatedDF, tf, idf); queue.insertWithOverflow(r); } List<TermIDF> results = new LinkedList<TermIDF>(); while (queue.size() > 0) { results.add(0, queue.pop()); } return results; }
/** * Recursively add a new entry to this node. <code>hashBits</code> is * the number of bits that are still set in the hash. When this value * reaches a number that is less than or equal to <tt>0</tt>, a leaf * node needs to be created since it means that a collision occurred * on the 32 bits of the hash. */ abstract Node<K, V> put(K key, int hash, int hashBits, V value, MutableValueInt newValue);