+++ /dev/null
-package org.apache.lucene.facet.taxonomy.writercache.cl2o;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.apache.lucene.facet.taxonomy.CategoryPath;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * HashMap to store colliding labels. See {@link CompactLabelToOrdinal} for
- * details.
- *
- * @lucene.experimental
- */
-public class CollisionMap {
-
- private int capacity;
- private float loadFactor;
- private int size;
- private int threshold;
-
- static class Entry {
- int offset;
- int cid;
- Entry next;
- int hash;
-
- Entry(int offset, int cid, int h, Entry e) {
- this.offset = offset;
- this.cid = cid;
- this.next = e;
- this.hash = h;
- }
- }
-
- private CharBlockArray labelRepository;
-
- private Entry[] entries;
-
- public CollisionMap(CharBlockArray labelRepository) {
- this(16 * 1024, 0.75f, labelRepository);
- }
-
- public CollisionMap(int initialCapacity, CharBlockArray labelRepository) {
- this(initialCapacity, 0.75f, labelRepository);
- }
-
- private CollisionMap(int initialCapacity, float loadFactor, CharBlockArray labelRepository) {
- this.labelRepository = labelRepository;
- this.loadFactor = loadFactor;
- this.capacity = CompactLabelToOrdinal.determineCapacity(2, initialCapacity);
-
- this.entries = new Entry[this.capacity];
- this.threshold = (int) (this.capacity * this.loadFactor);
- }
-
- public int size() {
- return this.size;
- }
-
- public int capacity() {
- return this.capacity;
- }
-
- private void grow() {
- int newCapacity = this.capacity * 2;
- Entry[] newEntries = new Entry[newCapacity];
- Entry[] src = this.entries;
-
- for (int j = 0; j < src.length; j++) {
- Entry e = src[j];
- if (e != null) {
- src[j] = null;
- do {
- Entry next = e.next;
- int hash = e.hash;
- int i = indexFor(hash, newCapacity);
- e.next = newEntries[i];
- newEntries[i] = e;
- e = next;
- } while (e != null);
- }
- }
-
- this.capacity = newCapacity;
- this.entries = newEntries;
- this.threshold = (int) (this.capacity * this.loadFactor);
- }
-
- public int get(CategoryPath label, int hash) {
- int bucketIndex = indexFor(hash, this.capacity);
- Entry e = this.entries[bucketIndex];
-
- while (e != null && !(hash == e.hash && label.equalsToSerialized(this.labelRepository, e.offset))) {
- e = e.next;
- }
- if (e == null) {
- return LabelToOrdinal.InvalidOrdinal;
- }
-
- return e.cid;
- }
-
- public int get(CategoryPath label, int prefixLen, int hash) {
- int bucketIndex = indexFor(hash, this.capacity);
- Entry e = this.entries[bucketIndex];
-
- while (e != null && !(hash == e.hash && label.equalsToSerialized(prefixLen, this.labelRepository, e.offset))) {
- e = e.next;
- }
- if (e == null) {
- return LabelToOrdinal.InvalidOrdinal;
- }
-
- return e.cid;
- }
-
- public int addLabel(CategoryPath label, int hash, int cid) {
- int bucketIndex = indexFor(hash, this.capacity);
- for (Entry e = this.entries[bucketIndex]; e != null; e = e.next) {
- if (e.hash == hash && label.equalsToSerialized(this.labelRepository, e.offset)) {
- return e.cid;
- }
- }
-
- // new string; add to label repository
- int offset = this.labelRepository.length();
- try {
- label.serializeAppendTo(labelRepository);
- } catch (IOException e) {
- // can't happen, because labelRepository.append() doesn't throw an exception
- }
-
- addEntry(offset, cid, hash, bucketIndex);
- return cid;
- }
-
- public int addLabel(CategoryPath label, int prefixLen, int hash, int cid) {
- int bucketIndex = indexFor(hash, this.capacity);
- for (Entry e = this.entries[bucketIndex]; e != null; e = e.next) {
- if (e.hash == hash && label.equalsToSerialized(prefixLen, this.labelRepository, e.offset)) {
- return e.cid;
- }
- }
-
- // new string; add to label repository
- int offset = this.labelRepository.length();
- try {
- label.serializeAppendTo(prefixLen, labelRepository);
- } catch (IOException e) {
- // can't happen, because labelRepository.append() doesn't throw an exception
- }
-
- addEntry(offset, cid, hash, bucketIndex);
- return cid;
- }
-
- /**
- * This method does not check if the same value is already
- * in the map because we pass in an char-array offset, so
- * so we now that we're in resize-mode here.
- */
- public void addLabelOffset(int hash, int offset, int cid) {
- int bucketIndex = indexFor(hash, this.capacity);
- addEntry(offset, cid, hash, bucketIndex);
- }
-
- private void addEntry(int offset, int cid, int hash, int bucketIndex) {
- Entry e = this.entries[bucketIndex];
- this.entries[bucketIndex] = new Entry(offset, cid, hash, e);
- if (this.size++ >= this.threshold) {
- grow();
- }
- }
-
- Iterator<CollisionMap.Entry> entryIterator() {
- return new EntryIterator(entries, size);
- }
-
- /**
- * Returns index for hash code h.
- */
- static int indexFor(int h, int length) {
- return h & (length - 1);
- }
-
- /**
- * Returns an estimate of the memory usage of this CollisionMap.
- * @return The approximate number of bytes used by this structure.
- */
- int getMemoryUsage() {
- int memoryUsage = 0;
- if (this.entries != null) {
- for (Entry e : this.entries) {
- if (e != null) {
- memoryUsage += (4 * 4);
- for (Entry ee = e.next; ee != null; ee = ee.next) {
- memoryUsage += (4 * 4);
- }
- }
- }
- }
- return memoryUsage;
- }
-
- private class EntryIterator implements Iterator<Entry> {
- Entry next; // next entry to return
- int index; // current slot
- Entry[] ents;
-
- EntryIterator(Entry[] entries, int size) {
- this.ents = entries;
- Entry[] t = entries;
- int i = t.length;
- Entry n = null;
- if (size != 0) { // advance to first entry
- while (i > 0 && (n = t[--i]) == null) {
- // advance
- }
- }
- this.next = n;
- this.index = i;
- }
-
- public boolean hasNext() {
- return this.next != null;
- }
-
- public Entry next() {
- Entry e = this.next;
- if (e == null) throw new NoSuchElementException();
-
- Entry n = e.next;
- Entry[] t = ents;
- int i = this.index;
- while (n == null && i > 0) {
- n = t[--i];
- }
- this.index = i;
- this.next = n;
- return e;
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- }
-
-}