| Index: src/java/org/apache/lucene/index/cache/ByteArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/ByteArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/ByteArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,120 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/* :TODO: javadocs */
|
| +public class ByteArrayCacheKey extends CacheKey {
|
| +
|
| + /**
|
| + * Interface to parse bytes from document fields.
|
| + */
|
| + public interface ByteParser {
|
| + /** Return a byte representation of this field's value. */
|
| + public byte parseByte(String string);
|
| + }
|
| +
|
| + private static final ByteParser DEFAULT_PARSER = new ByteParser() {
|
| + public byte parseByte(String value) {
|
| + return Byte.parseByte(value);
|
| + }
|
| + };
|
| +
|
| + String field;
|
| + ByteParser parser = DEFAULT_PARSER;
|
| +
|
| + public ByteArrayCacheKey(String f, ByteParser p) {
|
| + this(f);
|
| + if (null != p) parser = p;
|
| + }
|
| + public ByteArrayCacheKey(String f) {
|
| + field = f;
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + result = prime * result + ((parser == null) ? 0 : parser.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final ByteArrayCacheKey other = (ByteArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + if (parser == null) {
|
| + if (other.parser != null)
|
| + return false;
|
| + } else if (!parser.equals(other.parser))
|
| + return false;
|
| + return true;
|
| + }
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getByteArray(reader));
|
| + }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data)
|
| + throws UnsupportedOperationException {
|
| +
|
| + byte[] results = new byte[starts[starts.length-1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + byte[] src = (byte[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + public boolean isMergable() { return true; }
|
| +
|
| + protected byte[] getByteArray(IndexReader reader) throws IOException {
|
| +
|
| + final byte[] retArray = new byte[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| + byte termval = parser.parseByte(term.text());
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return retArray;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/ShortFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/ShortFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/ShortFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,44 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +public class ShortFieldCacheKey extends ShortArrayCacheKey {
|
| +
|
| + public ShortFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public ShortFieldCacheKey(String f, ShortParser p) {
|
| + super(f, p);
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + final short[] retArray = getShortArray(reader);
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Short(retArray[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return new Short(retArray[doc]);
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public boolean isMergable() { return false; }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/LongFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/LongFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/LongFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,43 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +public class LongFieldCacheKey extends LongArrayCacheKey {
|
| +
|
| + public LongFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public LongFieldCacheKey(String f, LongParser p) {
|
| + super(f, p);
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + final long[] retArray = getLongArray(reader);
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Long(retArray[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return new Long(retArray[doc]);
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public boolean isMergable() { return false; }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/FloatArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/FloatArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/FloatArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,124 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable floats.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public class FloatArrayCacheKey extends CacheKey {
|
| +
|
| + /**
|
| + * Interface to parse floats from document fields.
|
| + */
|
| + public interface FloatParser {
|
| + /** Return a float representation of this field's value. */
|
| + public float parseFloat(String string);
|
| + }
|
| +
|
| + private static final FloatParser DEFAULT_PARSER = new FloatParser() {
|
| + public float parseFloat(String value) {
|
| + return Float.parseFloat(value);
|
| + }
|
| + };
|
| +
|
| + String field;
|
| + FloatParser parser = DEFAULT_PARSER;
|
| +
|
| + public FloatArrayCacheKey(String f, FloatParser p) {
|
| + this(f);
|
| + if (null != p) parser = p;
|
| + }
|
| + public FloatArrayCacheKey(String f) {
|
| + field = f;
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + result = prime * result + ((parser == null) ? 0 : parser.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final FloatArrayCacheKey other = (FloatArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + if (parser == null) {
|
| + if (other.parser != null)
|
| + return false;
|
| + } else if (!parser.equals(other.parser))
|
| + return false;
|
| + return true;
|
| + }
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getFloatArray(reader));
|
| + }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data)
|
| + throws UnsupportedOperationException {
|
| +
|
| + float[] results = new float[starts[starts.length-1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + float[] src = (float[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + public boolean isMergable() { return true; }
|
| +
|
| + protected float[] getFloatArray(IndexReader reader) throws IOException {
|
| + final float[] retArray = new float[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| + float termval = parser.parseFloat(term.text());
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return retArray;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/StringArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/StringArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/StringArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,99 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable Strings.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public class StringArrayCacheKey extends CacheKey {
|
| +
|
| + String field;
|
| +
|
| + public StringArrayCacheKey(String f) {
|
| + field = f.intern();
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final StringArrayCacheKey other = (StringArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| +
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| +
|
| + final String[] retArray = new String[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| + String termval = term.text();
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return new CacheData(retArray);
|
| + }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data)
|
| + throws UnsupportedOperationException {
|
| +
|
| + String[] results = new String[starts[starts.length-1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + String[] src = (String[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + public boolean isMergable() { return true; }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/Cache.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/Cache.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/Cache.java (revision 0)
|
| @@ -0,0 +1,54 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +/**
|
| + * A simple Interface for modeling some form of Cache
|
| + */
|
| +public interface Cache {
|
| +
|
| + /**
|
| + * Get data from the Cache, returns null if the key is not found
|
| + * in the cache.
|
| + */
|
| + public CacheData get(CacheKey key);
|
| +
|
| + /**
|
| + * Puts data in the Cache.
|
| + */
|
| + public void put(CacheKey key, CacheData data);
|
| + /**
|
| + * returns true if the Cache contains data for the specified key.
|
| + */
|
| + public boolean containsKey(CacheKey key);
|
| +
|
| + /**
|
| + * Called when this Cache will no longer be used anymore, so that
|
| + * it can free any external resources it may have.
|
| + */
|
| + public void close();
|
| +
|
| + public static CacheFactory FACTORY = new CacheFactory() {
|
| + public Cache getCache(IndexReader r) {
|
| + return new SimpleMapCache();
|
| + }
|
| + };
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/FieldValues.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/FieldValues.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/FieldValues.java (revision 0)
|
| @@ -0,0 +1,7 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +
|
| +public interface FieldValues {
|
| + Comparable getOrd(int doc);
|
| + Comparable getValue(int doc);
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/ByteFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/ByteFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/ByteFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,43 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +
|
| +public class ByteFieldCacheKey extends ByteArrayCacheKey {
|
| +
|
| + public ByteFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public ByteFieldCacheKey(String f, ByteParser p) {
|
| + super(f, p);
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + final byte[] retArray = getByteArray(reader);
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Byte(retArray[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return new Byte(retArray[doc]);
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/DoubleArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/DoubleArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/DoubleArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,128 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable doubles.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating CacheData based on an IndexReader instance.
|
| + */
|
| +public class DoubleArrayCacheKey extends CacheKey {
|
| +
|
| + /**
|
| + * Interface to parse doubles from document fields.
|
| + */
|
| + public interface DoubleParser {
|
| + /** Return a double representation of this field's value. */
|
| + public double parseDouble(String string);
|
| + }
|
| +
|
| + private static final DoubleParser DEFAULT_PARSER = new DoubleParser() {
|
| + public double parseDouble(String value) {
|
| + return Double.parseDouble(value);
|
| + }
|
| + };
|
| +
|
| + String field;
|
| + DoubleParser parser = DEFAULT_PARSER;
|
| +
|
| + public DoubleArrayCacheKey(String f, DoubleParser p) {
|
| + this(f);
|
| + if (null != p)
|
| + parser = p;
|
| + }
|
| +
|
| + public DoubleArrayCacheKey(String f) {
|
| + field = f;
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + result = prime * result + ((parser == null) ? 0 : parser.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final DoubleArrayCacheKey other = (DoubleArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + if (parser == null) {
|
| + if (other.parser != null)
|
| + return false;
|
| + } else if (!parser.equals(other.parser))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getDoubleArray(reader));
|
| + }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data) throws UnsupportedOperationException {
|
| +
|
| + double[] results = new double[starts[starts.length - 1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + double[] src = (double[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + public boolean isMergable() {
|
| + return true;
|
| + }
|
| +
|
| + protected double[] getDoubleArray(IndexReader reader) throws IOException {
|
| + final double[] retArray = new double[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms(new Term(field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term == null || term.field() != field)
|
| + break;
|
| + double termval = parser.parseDouble(term.text());
|
| + termDocs.seek(termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return retArray;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/FloatFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/FloatFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/FloatFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,69 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable floats.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating CacheData based on an IndexReader instance.
|
| + */
|
| +public class FloatFieldCacheKey extends FloatArrayCacheKey {
|
| +
|
| + public FloatFieldCacheKey(String f, FloatParser p) {
|
| + super(f,p);
|
| + }
|
| +
|
| + public FloatFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + final float[] retArray = getFloatArray(reader);
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Float(retArray[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return new Float(retArray[doc]);
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public boolean isMergable() { return false; }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/StringFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/StringFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/StringFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,66 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable Strings. Caches all unique Strings as well
|
| + * as lookup indexes.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public class StringFieldCacheKey extends StringIndexCacheKey {
|
| +
|
| +
|
| + public StringFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| +
|
| + final StringIndex stringIndex = getStringIndex(reader, field);
|
| +
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Integer(stringIndex.order[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return stringIndex.lookup[stringIndex.order[doc]];
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public boolean isMergable() { return false; }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/DoubleFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/DoubleFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/DoubleFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,67 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable doubles.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating CacheData based on an IndexReader instance.
|
| + */
|
| +public class DoubleFieldCacheKey extends DoubleArrayCacheKey {
|
| +
|
| + public DoubleFieldCacheKey(String f, DoubleParser p) {
|
| + super(f,p);
|
| + }
|
| +
|
| + public DoubleFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + final double[] retArray = getDoubleArray(reader);
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Double(retArray[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return new Double(retArray[doc]);
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/SimpleMapCache.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/SimpleMapCache.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/SimpleMapCache.java (revision 0)
|
| @@ -0,0 +1,55 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import java.util.Collections;
|
| +import java.util.HashMap;
|
| +import java.util.Map;
|
| +import java.util.Set;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +
|
| +/**
|
| + * A simple Map based Cache.
|
| + *
|
| + */
|
| +public class SimpleMapCache implements Cache {
|
| +
|
| + private Map data = new HashMap();
|
| +
|
| + public SimpleMapCache() { /* NOOP */ }
|
| +
|
| + public synchronized void close() { /* NOOP */ }
|
| +
|
| + public synchronized void put(CacheKey k, CacheData v) {
|
| + data.put(k, v);
|
| + }
|
| +
|
| + public synchronized boolean containsKey(CacheKey key) {
|
| + return data.containsKey(key);
|
| + }
|
| + public synchronized Set keySet() {
|
| + return Collections.unmodifiableSet(data.keySet());
|
| + }
|
| +
|
| + public synchronized CacheData get(CacheKey key) {
|
| + return (CacheData) data.get(key);
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/CacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/CacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/CacheKey.java (revision 0)
|
| @@ -0,0 +1,132 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable data.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public abstract class CacheKey {
|
| +
|
| + public abstract boolean equals(Object o);
|
| + public abstract int hashCode();
|
| +
|
| + /**
|
| + * Builds up the CacheData associated with this Key for the
|
| + * specified IndexReader.
|
| + */
|
| + public abstract CacheData buildData(IndexReader r) throws IOException;
|
| +
|
| + /**
|
| + * Merges the CacheData returned by buildData for various IndexReaders
|
| + * such that the result is the same as if buildData had been called on a
|
| + * MultiReader wrapping those IndexReaders.
|
| + *
|
| + * @param starts from a MultiReader, n+1 elements, where the first n are the starting offsets of each IndexReader and the last element is the total maxDoc.
|
| + * @param data n elements resulting from n calls to buildData
|
| + * @exception UnsupportedOperationException unless isMergable returns true.
|
| + */
|
| + public CacheData mergeData(int[] starts, CacheData[] data)
|
| + throws UnsupportedOperationException {
|
| +
|
| + throw new UnsupportedOperationException
|
| + ("data from this CacheKey cannot be merged");
|
| + }
|
| +
|
| + /**
|
| + * Returns true if mergeData is a supported method for this CacheKey
|
| + *
|
| + * @see #mergeData
|
| + */
|
| + public boolean isMergable() {
|
| + return false;
|
| + }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return false;
|
| + }
|
| +
|
| + /** The pattern used to detect integer values in a field */
|
| + /** removed for java 1.3 compatibility
|
| + protected static final Pattern pIntegers = Pattern.compile ("[0-9\\-]+");
|
| + **/
|
| +
|
| + /** The pattern used to detect float values in a field */
|
| + /**
|
| + * removed for java 1.3 compatibility
|
| + * protected static final Object pFloats = Pattern.compile ("[0-9+\\-\\.eEfFdD]+");
|
| + */
|
| +
|
| + public static CacheKey getAutoCacheKey(IndexReader reader, String field) throws IOException {
|
| + field = ((String)field).intern();
|
| + TermEnum enumerator = reader.terms (new Term (field, ""));
|
| + try {
|
| + Term term = enumerator.term();
|
| + if (term == null) {
|
| + throw new RuntimeException ("no terms in field " + field + " - cannot determine sort type");
|
| + }
|
| + CacheKey ret = null;
|
| + if (term.field() == field) {
|
| + String termtext = term.text().trim();
|
| +
|
| + /**
|
| + * Java 1.4 level code:
|
| +
|
| + if (pIntegers.matcher(termtext).matches())
|
| + return IntegerSortedHitQueue.comparator (reader, enumerator, field);
|
| +
|
| + else if (pFloats.matcher(termtext).matches())
|
| + return FloatSortedHitQueue.comparator (reader, enumerator, field);
|
| + */
|
| +
|
| + // Java 1.3 level code:
|
| + try {
|
| + Integer.parseInt (termtext);
|
| + ret = new IntFieldCacheKey(field);
|
| + } catch (NumberFormatException nfe1) {
|
| + try {
|
| + Long.parseLong(termtext);
|
| + ret = new LongFieldCacheKey(field);
|
| + } catch (NumberFormatException nfe2) {
|
| + try {
|
| + Float.parseFloat (termtext);
|
| + ret = new FloatFieldCacheKey(field);
|
| + } catch (NumberFormatException nfe3) {
|
| + ret = new StringFieldCacheKey(field);
|
| + }
|
| + }
|
| + }
|
| + } else {
|
| + throw new RuntimeException ("field \"" + field + "\" does not appear to be indexed");
|
| + }
|
| + return ret;
|
| + } finally {
|
| + enumerator.close();
|
| + }
|
| +
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/IntArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/IntArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/IntArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,126 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable ints.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating CacheData based on an IndexReader instance.
|
| + */
|
| +public class IntArrayCacheKey extends CacheKey {
|
| +
|
| + /**
|
| + * Interface to parse ints from document fields.
|
| + */
|
| + public interface IntParser {
|
| + /** Return an integer representation of this field's value. */
|
| + public int parseInt(String string);
|
| + }
|
| +
|
| + private static final IntParser DEFAULT_PARSER = new IntParser() {
|
| + public int parseInt(String value) {
|
| + return Integer.parseInt(value);
|
| + }
|
| + };
|
| +
|
| + String field;
|
| + IntParser parser = DEFAULT_PARSER;
|
| +
|
| + public IntArrayCacheKey(String f, IntParser p) {
|
| + this(f);
|
| + if (null != p)
|
| + parser = p;
|
| + }
|
| +
|
| + public IntArrayCacheKey(String f) {
|
| + field = f;
|
| + }
|
| +
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + result = prime * result + ((parser == null) ? 0 : parser.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final IntArrayCacheKey other = (IntArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + if (parser == null) {
|
| + if (other.parser != null)
|
| + return false;
|
| + } else if (!parser.equals(other.parser))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getIntArray(reader));
|
| + }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data) throws UnsupportedOperationException {
|
| + int[] results = new int[starts[starts.length - 1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + int[] src = (int[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + protected int[] getIntArray(IndexReader reader) throws IOException {
|
| + final int[] retArray = new int[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms(new Term(field, ""));
|
| + int cnt = 0;
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term == null || term.field() != field)
|
| + break;
|
| + int termval = parser.parseInt(term.text());
|
| + termDocs.seek(termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + cnt++;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return retArray;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/LongArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/LongArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/LongArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,109 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable longs.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public class LongArrayCacheKey extends CacheKey {
|
| +
|
| + private static final LongParser DEFAULT_PARSER = new LongParser() {
|
| + public long parseLong(String value) {
|
| + return Long.parseLong(value);
|
| + }
|
| + };
|
| +
|
| + String field;
|
| +
|
| + LongParser parser = DEFAULT_PARSER;
|
| + public LongArrayCacheKey(String f) {
|
| + field = f;
|
| + }
|
| +
|
| + public LongArrayCacheKey(String f, LongParser p) {
|
| + this(f);
|
| + if (null != p) parser = p;
|
| + }
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getLongArray(reader));
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final LongArrayCacheKey other = (LongArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + if (parser == null) {
|
| + if (other.parser != null)
|
| + return false;
|
| + } else if (!parser.equals(other.parser))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + protected long[] getLongArray(IndexReader reader) throws IOException {
|
| +
|
| + final long[] retArray = new long[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| + long termval = parser.parseLong(term.text());
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return retArray;
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + result = prime * result + ((parser == null) ? 0 : parser.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean isMergable() { return true; }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data)
|
| + throws UnsupportedOperationException {
|
| +
|
| + long[] results = new long[starts[starts.length-1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + long[] src = (long[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + /**
|
| + * Interface to parse longs from document fields.
|
| + */
|
| + public interface LongParser {
|
| + /** Return a long representation of this field's value. */
|
| + public long parseLong(String string);
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/IntFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/IntFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/IntFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,67 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable ints.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating CacheData based on an IndexReader instance.
|
| + */
|
| +public class IntFieldCacheKey extends IntArrayCacheKey {
|
| +
|
| +
|
| + public IntFieldCacheKey(String f, IntParser p) {
|
| + super(f,p);
|
| + }
|
| +
|
| + public IntFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + final int[] retArray = getIntArray(reader);
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Integer(retArray[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return new Integer(retArray[doc]);
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public boolean isMergable() { return false; }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/ShortArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/ShortArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/ShortArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,107 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable shorts.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public class ShortArrayCacheKey extends CacheKey {
|
| + /**
|
| + * Interface to parse shortss from document fields.
|
| + */
|
| + public interface ShortParser {
|
| + /** Return a short representation of this field's value. */
|
| + public short parseShort(String string);
|
| + }
|
| +
|
| + private static final ShortParser DEFAULT_PARSER = new ShortParser() {
|
| + public short parseShort(String value) {
|
| + return Short.parseShort(value);
|
| + }
|
| + };
|
| +
|
| + String field;
|
| + ShortParser parser = DEFAULT_PARSER;
|
| +
|
| + public ShortArrayCacheKey(String f, ShortParser p) {
|
| + this(f);
|
| + if (null != p) parser = p;
|
| + }
|
| + public ShortArrayCacheKey(String f) {
|
| + field = f;
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + result = prime * result + ((parser == null) ? 0 : parser.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final ShortArrayCacheKey other = (ShortArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + if (parser == null) {
|
| + if (other.parser != null)
|
| + return false;
|
| + } else if (!parser.equals(other.parser))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getShortArray(reader));
|
| + }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data)
|
| + throws UnsupportedOperationException {
|
| +
|
| + short[] results = new short[starts[starts.length-1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + short[] src = (short[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + public boolean isMergable() { return true; }
|
| +
|
| + protected short[] getShortArray(IndexReader reader) throws IOException {
|
| + final short[] retArray = new short[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| + short termval = parser.parseShort(term.text());
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return retArray;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/CacheFactory.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/CacheFactory.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/CacheFactory.java (revision 0)
|
| @@ -0,0 +1,33 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +
|
| +/**
|
| + *
|
| + *
|
| + */
|
| +public interface CacheFactory {
|
| +
|
| + public Cache getCache(IndexReader r) throws IOException;
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/StringIndexCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/StringIndexCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/StringIndexCacheKey.java (revision 0)
|
| @@ -0,0 +1,136 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable Strings. Caches all unique Strings as well
|
| + * as lookup indexes.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public class StringIndexCacheKey extends CacheKey {
|
| +
|
| + public static class StringIndex {
|
| +
|
| + /** All the term values, in natural order. */
|
| + public final String[] lookup;
|
| +
|
| + /** For each document, an index into the lookup array. */
|
| + public final int[] order;
|
| +
|
| + /** Creates one of these objects */
|
| + public StringIndex (int[] values, String[] lookup) {
|
| + this.order = values;
|
| + this.lookup = lookup;
|
| + }
|
| + }
|
| +
|
| + String field;
|
| +
|
| + public StringIndexCacheKey(String f) {
|
| + field = f.intern();
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final StringIndexCacheKey other = (StringIndexCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getStringIndex(reader, field));
|
| + }
|
| +
|
| + protected StringIndex getStringIndex(IndexReader reader, String field) throws IOException {
|
| + final int[] retArray = new int[reader.maxDoc()];
|
| + String[] mterms = new String[reader.maxDoc()+1];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + int t = 0; // current term number
|
| +
|
| + // an entry for documents that have no terms in this field
|
| + // should a document with no terms be at top or bottom?
|
| + // this puts them at the top - if it is changed, FieldDocSortedHitQueue
|
| + // needs to change as well.
|
| + mterms[t++] = null;
|
| +
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| +
|
| + // store term text
|
| + // we expect that there is at most one term per document
|
| + if (t >= mterms.length)
|
| + throw new RuntimeException
|
| + ("there are more terms than documents in field \"" + field +
|
| + "\", but it's impossible to sort on tokenized fields");
|
| + mterms[t] = term.text();
|
| +
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = t;
|
| + }
|
| +
|
| + t++;
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + if (t == 0) {
|
| + // if there are no terms, make the term array
|
| + // have a single null entry
|
| + mterms = new String[1];
|
| + } else if (t < mterms.length) {
|
| + // if there are less terms than documents,
|
| + // trim off the dead array space
|
| + String[] terms = new String[t];
|
| + System.arraycopy (mterms, 0, terms, 0, t);
|
| + mterms = terms;
|
| + }
|
| +
|
| + return new StringIndex(retArray, mterms);
|
| + }
|
| +
|
| + public boolean isMergable() { return false; }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/CacheData.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/CacheData.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/CacheData.java (revision 0)
|
| @@ -0,0 +1,31 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +
|
| +/**
|
| + * Encapsulates cached data
|
| + *
|
| + */
|
| +public class CacheData {
|
| + public CacheData(Object payload) {
|
| + this.payload = payload;
|
| + }
|
| + private Object payload;
|
| + public Object getPayload() { return payload; }
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/ByteArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/ByteArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/ByteArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,120 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/* :TODO: javadocs */
|
| +public class ByteArrayCacheKey extends CacheKey {
|
| +
|
| + /**
|
| + * Interface to parse bytes from document fields.
|
| + */
|
| + public interface ByteParser {
|
| + /** Return a byte representation of this field's value. */
|
| + public byte parseByte(String string);
|
| + }
|
| +
|
| + private static final ByteParser DEFAULT_PARSER = new ByteParser() {
|
| + public byte parseByte(String value) {
|
| + return Byte.parseByte(value);
|
| + }
|
| + };
|
| +
|
| + String field;
|
| + ByteParser parser = DEFAULT_PARSER;
|
| +
|
| + public ByteArrayCacheKey(String f, ByteParser p) {
|
| + this(f);
|
| + if (null != p) parser = p;
|
| + }
|
| + public ByteArrayCacheKey(String f) {
|
| + field = f;
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + result = prime * result + ((parser == null) ? 0 : parser.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final ByteArrayCacheKey other = (ByteArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + if (parser == null) {
|
| + if (other.parser != null)
|
| + return false;
|
| + } else if (!parser.equals(other.parser))
|
| + return false;
|
| + return true;
|
| + }
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getByteArray(reader));
|
| + }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data)
|
| + throws UnsupportedOperationException {
|
| +
|
| + byte[] results = new byte[starts[starts.length-1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + byte[] src = (byte[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + public boolean isMergable() { return true; }
|
| +
|
| + protected byte[] getByteArray(IndexReader reader) throws IOException {
|
| +
|
| + final byte[] retArray = new byte[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| + byte termval = parser.parseByte(term.text());
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return retArray;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/ByteFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/ByteFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/ByteFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,43 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +
|
| +public class ByteFieldCacheKey extends ByteArrayCacheKey {
|
| +
|
| + public ByteFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public ByteFieldCacheKey(String f, ByteParser p) {
|
| + super(f, p);
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + final byte[] retArray = getByteArray(reader);
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Byte(retArray[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return new Byte(retArray[doc]);
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/Cache.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/Cache.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/Cache.java (revision 0)
|
| @@ -0,0 +1,54 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +/**
|
| + * A simple Interface for modeling some form of Cache
|
| + */
|
| +public interface Cache {
|
| +
|
| + /**
|
| + * Get data from the Cache, returns null if the key is not found
|
| + * in the cache.
|
| + */
|
| + public CacheData get(CacheKey key);
|
| +
|
| + /**
|
| + * Puts data in the Cache.
|
| + */
|
| + public void put(CacheKey key, CacheData data);
|
| + /**
|
| + * returns true if the Cache contains data for the specified key.
|
| + */
|
| + public boolean containsKey(CacheKey key);
|
| +
|
| + /**
|
| + * Called when this Cache will no longer be used anymore, so that
|
| + * it can free any external resources it may have.
|
| + */
|
| + public void close();
|
| +
|
| + public static CacheFactory FACTORY = new CacheFactory() {
|
| + public Cache getCache(IndexReader r) {
|
| + return new SimpleMapCache();
|
| + }
|
| + };
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/CacheData.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/CacheData.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/CacheData.java (revision 0)
|
| @@ -0,0 +1,31 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +
|
| +/**
|
| + * Encapsulates cached data
|
| + *
|
| + */
|
| +public class CacheData {
|
| + public CacheData(Object payload) {
|
| + this.payload = payload;
|
| + }
|
| + private Object payload;
|
| + public Object getPayload() { return payload; }
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/CacheFactory.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/CacheFactory.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/CacheFactory.java (revision 0)
|
| @@ -0,0 +1,33 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +
|
| +/**
|
| + *
|
| + *
|
| + */
|
| +public interface CacheFactory {
|
| +
|
| + public Cache getCache(IndexReader r) throws IOException;
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/CacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/CacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/CacheKey.java (revision 0)
|
| @@ -0,0 +1,132 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable data.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public abstract class CacheKey {
|
| +
|
| + public abstract boolean equals(Object o);
|
| + public abstract int hashCode();
|
| +
|
| + /**
|
| + * Builds up the CacheData associated with this Key for the
|
| + * specified IndexReader.
|
| + */
|
| + public abstract CacheData buildData(IndexReader r) throws IOException;
|
| +
|
| + /**
|
| + * Merges the CacheData returned by buildData for various IndexReaders
|
| + * such that the result is the same as if buildData had been called on a
|
| + * MultiReader wrapping those IndexReaders.
|
| + *
|
| + * @param starts from a MultiReader, n+1 elements, where the first n are the starting offsets of each IndexReader and the last element is the total maxDoc.
|
| + * @param data n elements resulting from n calls to buildData
|
| + * @exception UnsupportedOperationException unless isMergable returns true.
|
| + */
|
| + public CacheData mergeData(int[] starts, CacheData[] data)
|
| + throws UnsupportedOperationException {
|
| +
|
| + throw new UnsupportedOperationException
|
| + ("data from this CacheKey cannot be merged");
|
| + }
|
| +
|
| + /**
|
| + * Returns true if mergeData is a supported method for this CacheKey
|
| + *
|
| + * @see #mergeData
|
| + */
|
| + public boolean isMergable() {
|
| + return false;
|
| + }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return false;
|
| + }
|
| +
|
| + /** The pattern used to detect integer values in a field */
|
| + /** removed for java 1.3 compatibility
|
| + protected static final Pattern pIntegers = Pattern.compile ("[0-9\\-]+");
|
| + **/
|
| +
|
| + /** The pattern used to detect float values in a field */
|
| + /**
|
| + * removed for java 1.3 compatibility
|
| + * protected static final Object pFloats = Pattern.compile ("[0-9+\\-\\.eEfFdD]+");
|
| + */
|
| +
|
| + public static CacheKey getAutoCacheKey(IndexReader reader, String field) throws IOException {
|
| + field = ((String)field).intern();
|
| + TermEnum enumerator = reader.terms (new Term (field, ""));
|
| + try {
|
| + Term term = enumerator.term();
|
| + if (term == null) {
|
| + throw new RuntimeException ("no terms in field " + field + " - cannot determine sort type");
|
| + }
|
| + CacheKey ret = null;
|
| + if (term.field() == field) {
|
| + String termtext = term.text().trim();
|
| +
|
| + /**
|
| + * Java 1.4 level code:
|
| +
|
| + if (pIntegers.matcher(termtext).matches())
|
| + return IntegerSortedHitQueue.comparator (reader, enumerator, field);
|
| +
|
| + else if (pFloats.matcher(termtext).matches())
|
| + return FloatSortedHitQueue.comparator (reader, enumerator, field);
|
| + */
|
| +
|
| + // Java 1.3 level code:
|
| + try {
|
| + Integer.parseInt (termtext);
|
| + ret = new IntFieldCacheKey(field);
|
| + } catch (NumberFormatException nfe1) {
|
| + try {
|
| + Long.parseLong(termtext);
|
| + ret = new LongFieldCacheKey(field);
|
| + } catch (NumberFormatException nfe2) {
|
| + try {
|
| + Float.parseFloat (termtext);
|
| + ret = new FloatFieldCacheKey(field);
|
| + } catch (NumberFormatException nfe3) {
|
| + ret = new StringFieldCacheKey(field);
|
| + }
|
| + }
|
| + }
|
| + } else {
|
| + throw new RuntimeException ("field \"" + field + "\" does not appear to be indexed");
|
| + }
|
| + return ret;
|
| + } finally {
|
| + enumerator.close();
|
| + }
|
| +
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/DoubleArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/DoubleArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/DoubleArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,128 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable doubles.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating CacheData based on an IndexReader instance.
|
| + */
|
| +public class DoubleArrayCacheKey extends CacheKey {
|
| +
|
| + /**
|
| + * Interface to parse doubles from document fields.
|
| + */
|
| + public interface DoubleParser {
|
| + /** Return a double representation of this field's value. */
|
| + public double parseDouble(String string);
|
| + }
|
| +
|
| + private static final DoubleParser DEFAULT_PARSER = new DoubleParser() {
|
| + public double parseDouble(String value) {
|
| + return Double.parseDouble(value);
|
| + }
|
| + };
|
| +
|
| + String field;
|
| + DoubleParser parser = DEFAULT_PARSER;
|
| +
|
| + public DoubleArrayCacheKey(String f, DoubleParser p) {
|
| + this(f);
|
| + if (null != p)
|
| + parser = p;
|
| + }
|
| +
|
| + public DoubleArrayCacheKey(String f) {
|
| + field = f;
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + result = prime * result + ((parser == null) ? 0 : parser.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final DoubleArrayCacheKey other = (DoubleArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + if (parser == null) {
|
| + if (other.parser != null)
|
| + return false;
|
| + } else if (!parser.equals(other.parser))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getDoubleArray(reader));
|
| + }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data) throws UnsupportedOperationException {
|
| +
|
| + double[] results = new double[starts[starts.length - 1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + double[] src = (double[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + public boolean isMergable() {
|
| + return true;
|
| + }
|
| +
|
| + protected double[] getDoubleArray(IndexReader reader) throws IOException {
|
| + final double[] retArray = new double[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms(new Term(field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term == null || term.field() != field)
|
| + break;
|
| + double termval = parser.parseDouble(term.text());
|
| + termDocs.seek(termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return retArray;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/DoubleFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/DoubleFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/DoubleFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,67 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable doubles.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating CacheData based on an IndexReader instance.
|
| + */
|
| +public class DoubleFieldCacheKey extends DoubleArrayCacheKey {
|
| +
|
| + public DoubleFieldCacheKey(String f, DoubleParser p) {
|
| + super(f,p);
|
| + }
|
| +
|
| + public DoubleFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + final double[] retArray = getDoubleArray(reader);
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Double(retArray[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return new Double(retArray[doc]);
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/FieldValues.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/FieldValues.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/FieldValues.java (revision 0)
|
| @@ -0,0 +1,7 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +
|
| +public interface FieldValues {
|
| + Comparable getOrd(int doc);
|
| + Comparable getValue(int doc);
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/FloatArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/FloatArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/FloatArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,124 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable floats.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public class FloatArrayCacheKey extends CacheKey {
|
| +
|
| + /**
|
| + * Interface to parse floats from document fields.
|
| + */
|
| + public interface FloatParser {
|
| + /** Return a float representation of this field's value. */
|
| + public float parseFloat(String string);
|
| + }
|
| +
|
| + private static final FloatParser DEFAULT_PARSER = new FloatParser() {
|
| + public float parseFloat(String value) {
|
| + return Float.parseFloat(value);
|
| + }
|
| + };
|
| +
|
| + String field;
|
| + FloatParser parser = DEFAULT_PARSER;
|
| +
|
| + public FloatArrayCacheKey(String f, FloatParser p) {
|
| + this(f);
|
| + if (null != p) parser = p;
|
| + }
|
| + public FloatArrayCacheKey(String f) {
|
| + field = f;
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + result = prime * result + ((parser == null) ? 0 : parser.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final FloatArrayCacheKey other = (FloatArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + if (parser == null) {
|
| + if (other.parser != null)
|
| + return false;
|
| + } else if (!parser.equals(other.parser))
|
| + return false;
|
| + return true;
|
| + }
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getFloatArray(reader));
|
| + }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data)
|
| + throws UnsupportedOperationException {
|
| +
|
| + float[] results = new float[starts[starts.length-1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + float[] src = (float[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + public boolean isMergable() { return true; }
|
| +
|
| + protected float[] getFloatArray(IndexReader reader) throws IOException {
|
| + final float[] retArray = new float[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| + float termval = parser.parseFloat(term.text());
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return retArray;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/FloatFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/FloatFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/FloatFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,69 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable floats.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating CacheData based on an IndexReader instance.
|
| + */
|
| +public class FloatFieldCacheKey extends FloatArrayCacheKey {
|
| +
|
| + public FloatFieldCacheKey(String f, FloatParser p) {
|
| + super(f,p);
|
| + }
|
| +
|
| + public FloatFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + final float[] retArray = getFloatArray(reader);
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Float(retArray[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return new Float(retArray[doc]);
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public boolean isMergable() { return false; }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/IntArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/IntArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/IntArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,126 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable ints.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating CacheData based on an IndexReader instance.
|
| + */
|
| +public class IntArrayCacheKey extends CacheKey {
|
| +
|
| + /**
|
| + * Interface to parse ints from document fields.
|
| + */
|
| + public interface IntParser {
|
| + /** Return an integer representation of this field's value. */
|
| + public int parseInt(String string);
|
| + }
|
| +
|
| + private static final IntParser DEFAULT_PARSER = new IntParser() {
|
| + public int parseInt(String value) {
|
| + return Integer.parseInt(value);
|
| + }
|
| + };
|
| +
|
| + String field;
|
| + IntParser parser = DEFAULT_PARSER;
|
| +
|
| + public IntArrayCacheKey(String f, IntParser p) {
|
| + this(f);
|
| + if (null != p)
|
| + parser = p;
|
| + }
|
| +
|
| + public IntArrayCacheKey(String f) {
|
| + field = f;
|
| + }
|
| +
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + result = prime * result + ((parser == null) ? 0 : parser.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final IntArrayCacheKey other = (IntArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + if (parser == null) {
|
| + if (other.parser != null)
|
| + return false;
|
| + } else if (!parser.equals(other.parser))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getIntArray(reader));
|
| + }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data) throws UnsupportedOperationException {
|
| + int[] results = new int[starts[starts.length - 1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + int[] src = (int[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + protected int[] getIntArray(IndexReader reader) throws IOException {
|
| + final int[] retArray = new int[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms(new Term(field, ""));
|
| + int cnt = 0;
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term == null || term.field() != field)
|
| + break;
|
| + int termval = parser.parseInt(term.text());
|
| + termDocs.seek(termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + cnt++;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return retArray;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/IntFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/IntFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/IntFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,67 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable ints.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating CacheData based on an IndexReader instance.
|
| + */
|
| +public class IntFieldCacheKey extends IntArrayCacheKey {
|
| +
|
| +
|
| + public IntFieldCacheKey(String f, IntParser p) {
|
| + super(f,p);
|
| + }
|
| +
|
| + public IntFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + final int[] retArray = getIntArray(reader);
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Integer(retArray[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return new Integer(retArray[doc]);
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public boolean isMergable() { return false; }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/LongArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/LongArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/LongArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,109 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable longs.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public class LongArrayCacheKey extends CacheKey {
|
| +
|
| + private static final LongParser DEFAULT_PARSER = new LongParser() {
|
| + public long parseLong(String value) {
|
| + return Long.parseLong(value);
|
| + }
|
| + };
|
| +
|
| + String field;
|
| +
|
| + LongParser parser = DEFAULT_PARSER;
|
| + public LongArrayCacheKey(String f) {
|
| + field = f;
|
| + }
|
| +
|
| + public LongArrayCacheKey(String f, LongParser p) {
|
| + this(f);
|
| + if (null != p) parser = p;
|
| + }
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getLongArray(reader));
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final LongArrayCacheKey other = (LongArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + if (parser == null) {
|
| + if (other.parser != null)
|
| + return false;
|
| + } else if (!parser.equals(other.parser))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + protected long[] getLongArray(IndexReader reader) throws IOException {
|
| +
|
| + final long[] retArray = new long[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| + long termval = parser.parseLong(term.text());
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return retArray;
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + result = prime * result + ((parser == null) ? 0 : parser.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean isMergable() { return true; }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data)
|
| + throws UnsupportedOperationException {
|
| +
|
| + long[] results = new long[starts[starts.length-1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + long[] src = (long[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + /**
|
| + * Interface to parse longs from document fields.
|
| + */
|
| + public interface LongParser {
|
| + /** Return a long representation of this field's value. */
|
| + public long parseLong(String string);
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/LongFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/LongFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/LongFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,43 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +public class LongFieldCacheKey extends LongArrayCacheKey {
|
| +
|
| + public LongFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public LongFieldCacheKey(String f, LongParser p) {
|
| + super(f, p);
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + final long[] retArray = getLongArray(reader);
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Long(retArray[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return new Long(retArray[doc]);
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public boolean isMergable() { return false; }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/ShortArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/ShortArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/ShortArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,107 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable shorts.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public class ShortArrayCacheKey extends CacheKey {
|
| + /**
|
| + * Interface to parse shortss from document fields.
|
| + */
|
| + public interface ShortParser {
|
| + /** Return a short representation of this field's value. */
|
| + public short parseShort(String string);
|
| + }
|
| +
|
| + private static final ShortParser DEFAULT_PARSER = new ShortParser() {
|
| + public short parseShort(String value) {
|
| + return Short.parseShort(value);
|
| + }
|
| + };
|
| +
|
| + String field;
|
| + ShortParser parser = DEFAULT_PARSER;
|
| +
|
| + public ShortArrayCacheKey(String f, ShortParser p) {
|
| + this(f);
|
| + if (null != p) parser = p;
|
| + }
|
| + public ShortArrayCacheKey(String f) {
|
| + field = f;
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + result = prime * result + ((parser == null) ? 0 : parser.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final ShortArrayCacheKey other = (ShortArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + if (parser == null) {
|
| + if (other.parser != null)
|
| + return false;
|
| + } else if (!parser.equals(other.parser))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getShortArray(reader));
|
| + }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data)
|
| + throws UnsupportedOperationException {
|
| +
|
| + short[] results = new short[starts[starts.length-1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + short[] src = (short[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + public boolean isMergable() { return true; }
|
| +
|
| + protected short[] getShortArray(IndexReader reader) throws IOException {
|
| + final short[] retArray = new short[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| + short termval = parser.parseShort(term.text());
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return retArray;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/ShortFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/ShortFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/ShortFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,44 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +public class ShortFieldCacheKey extends ShortArrayCacheKey {
|
| +
|
| + public ShortFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public ShortFieldCacheKey(String f, ShortParser p) {
|
| + super(f, p);
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + final short[] retArray = getShortArray(reader);
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Short(retArray[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return new Short(retArray[doc]);
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public boolean isMergable() { return false; }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/SimpleMapCache.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/SimpleMapCache.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/SimpleMapCache.java (revision 0)
|
| @@ -0,0 +1,55 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import java.util.Collections;
|
| +import java.util.HashMap;
|
| +import java.util.Map;
|
| +import java.util.Set;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +
|
| +/**
|
| + * A simple Map based Cache.
|
| + *
|
| + */
|
| +public class SimpleMapCache implements Cache {
|
| +
|
| + private Map data = new HashMap();
|
| +
|
| + public SimpleMapCache() { /* NOOP */ }
|
| +
|
| + public synchronized void close() { /* NOOP */ }
|
| +
|
| + public synchronized void put(CacheKey k, CacheData v) {
|
| + data.put(k, v);
|
| + }
|
| +
|
| + public synchronized boolean containsKey(CacheKey key) {
|
| + return data.containsKey(key);
|
| + }
|
| + public synchronized Set keySet() {
|
| + return Collections.unmodifiableSet(data.keySet());
|
| + }
|
| +
|
| + public synchronized CacheData get(CacheKey key) {
|
| + return (CacheData) data.get(key);
|
| + }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/StringArrayCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/StringArrayCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/StringArrayCacheKey.java (revision 0)
|
| @@ -0,0 +1,99 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable Strings.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public class StringArrayCacheKey extends CacheKey {
|
| +
|
| + String field;
|
| +
|
| + public StringArrayCacheKey(String f) {
|
| + field = f.intern();
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final StringArrayCacheKey other = (StringArrayCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| +
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| +
|
| + final String[] retArray = new String[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| + String termval = term.text();
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + return new CacheData(retArray);
|
| + }
|
| +
|
| + public CacheData mergeData(int[] starts, CacheData[] data)
|
| + throws UnsupportedOperationException {
|
| +
|
| + String[] results = new String[starts[starts.length-1]];
|
| + for (int i = 0; i < data.length; i++) {
|
| + String[] src = (String[]) data[i].getPayload();
|
| + System.arraycopy(src, 0, results, starts[i], src.length);
|
| + }
|
| + return new CacheData(results);
|
| + }
|
| +
|
| + public boolean isMergable() { return true; }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/StringFieldCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/StringFieldCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/StringFieldCacheKey.java (revision 0)
|
| @@ -0,0 +1,66 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import java.io.IOException;
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable Strings. Caches all unique Strings as well
|
| + * as lookup indexes.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public class StringFieldCacheKey extends StringIndexCacheKey {
|
| +
|
| +
|
| + public StringFieldCacheKey(String f) {
|
| + super(f);
|
| + }
|
| +
|
| + public int hashCode() {
|
| + return super.hashCode() * 31;
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| +
|
| + final StringIndex stringIndex = getStringIndex(reader, field);
|
| +
|
| + FieldValues fieldValues = new FieldValues() {
|
| +
|
| + public Comparable getOrd(int doc) {
|
| + return new Integer(stringIndex.order[doc]);
|
| + }
|
| +
|
| + public Comparable getValue(int doc) {
|
| + return stringIndex.lookup[stringIndex.order[doc]];
|
| + }
|
| +
|
| + };
|
| +
|
| + return new CacheData(fieldValues);
|
| + }
|
| +
|
| + public boolean isMergable() { return false; }
|
| +
|
| + public boolean usesFieldValues() {
|
| + return true;
|
| + }
|
| +}
|
| Index: src/java/org/apache/lucene/index/cache/StringIndexCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/cache/StringIndexCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/index/cache/StringIndexCacheKey.java (revision 0)
|
| @@ -0,0 +1,136 @@
|
| +package org.apache.lucene.index.cache;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/**
|
| + * A Key for identifying cacheable Strings. Caches all unique Strings as well
|
| + * as lookup indexes.
|
| + *
|
| + * CacheKey instances provide all of the functionality for generating
|
| + * CacheData based on an IndexReader instance.
|
| + */
|
| +public class StringIndexCacheKey extends CacheKey {
|
| +
|
| + public static class StringIndex {
|
| +
|
| + /** All the term values, in natural order. */
|
| + public final String[] lookup;
|
| +
|
| + /** For each document, an index into the lookup array. */
|
| + public final int[] order;
|
| +
|
| + /** Creates one of these objects */
|
| + public StringIndex (int[] values, String[] lookup) {
|
| + this.order = values;
|
| + this.lookup = lookup;
|
| + }
|
| + }
|
| +
|
| + String field;
|
| +
|
| + public StringIndexCacheKey(String f) {
|
| + field = f.intern();
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((field == null) ? 0 : field.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final StringIndexCacheKey other = (StringIndexCacheKey) obj;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| + return new CacheData(getStringIndex(reader, field));
|
| + }
|
| +
|
| + protected StringIndex getStringIndex(IndexReader reader, String field) throws IOException {
|
| + final int[] retArray = new int[reader.maxDoc()];
|
| + String[] mterms = new String[reader.maxDoc()+1];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + int t = 0; // current term number
|
| +
|
| + // an entry for documents that have no terms in this field
|
| + // should a document with no terms be at top or bottom?
|
| + // this puts them at the top - if it is changed, FieldDocSortedHitQueue
|
| + // needs to change as well.
|
| + mterms[t++] = null;
|
| +
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| +
|
| + // store term text
|
| + // we expect that there is at most one term per document
|
| + if (t >= mterms.length)
|
| + throw new RuntimeException
|
| + ("there are more terms than documents in field \"" + field +
|
| + "\", but it's impossible to sort on tokenized fields");
|
| + mterms[t] = term.text();
|
| +
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = t;
|
| + }
|
| +
|
| + t++;
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| +
|
| + if (t == 0) {
|
| + // if there are no terms, make the term array
|
| + // have a single null entry
|
| + mterms = new String[1];
|
| + } else if (t < mterms.length) {
|
| + // if there are less terms than documents,
|
| + // trim off the dead array space
|
| + String[] terms = new String[t];
|
| + System.arraycopy (mterms, 0, terms, 0, t);
|
| + mterms = terms;
|
| + }
|
| +
|
| + return new StringIndex(retArray, mterms);
|
| + }
|
| +
|
| + public boolean isMergable() { return false; }
|
| +
|
| +}
|
| Index: src/java/org/apache/lucene/index/DirectoryIndexReader.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/DirectoryIndexReader.java (revision 642339)
|
| +++ src/java/org/apache/lucene/index/DirectoryIndexReader.java (working copy)
|
| @@ -24,6 +24,8 @@
|
| import java.util.ArrayList; |
| import java.util.List; |
| |
| +import org.apache.lucene.index.cache.Cache; |
| +import org.apache.lucene.index.cache.SimpleMapCache; |
| import org.apache.lucene.store.Directory; |
| import org.apache.lucene.store.Lock; |
| import org.apache.lucene.store.LockObtainFailedException; |
| @@ -93,6 +95,7 @@
|
| reader = new MultiSegmentReader(directory, infos, closeDirectory); |
| } |
| reader.setDeletionPolicy(deletionPolicy); |
| + reader.useCacheFactory(Cache.FACTORY); |
| return reader; |
| } |
| }.run(); |
| @@ -100,9 +103,9 @@
|
| |
| public final synchronized IndexReader reopen() throws CorruptIndexException, IOException { |
| ensureOpen(); |
| - |
| if (this.hasChanges || this.isCurrent()) { |
| // the index hasn't changed - nothing to do here |
| + |
| return this; |
| } |
| |
| @@ -118,7 +121,7 @@
|
| newReader.init(directory, infos, closeDirectory); |
| newReader.deletionPolicy = deletionPolicy; |
| } |
| - |
| + newReader.useCacheFactory(Cache.FACTORY); |
| return newReader; |
| } |
| }.run(); |
| Index: src/java/org/apache/lucene/index/IndexReader.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/IndexReader.java (revision 642339)
|
| +++ src/java/org/apache/lucene/index/IndexReader.java (working copy)
|
| @@ -17,6 +17,7 @@
|
| * limitations under the License. |
| */ |
| |
| +import org.apache.lucene.index.cache.*; |
| import org.apache.lucene.document.Document; |
| import org.apache.lucene.document.FieldSelector; |
| import org.apache.lucene.search.Similarity; |
| @@ -93,6 +94,7 @@
|
| |
| private boolean closed; |
| protected boolean hasChanges; |
| + private Cache cache; |
| |
| private volatile int refCount; |
| |
| @@ -149,10 +151,24 @@
|
| protected IndexReader(Directory directory) { |
| this(); |
| this.directory = directory; |
| + //TODO: find best set points |
| + try { |
| + cache = Cache.FACTORY.getCache(this); |
| + } catch (IOException e) { |
| + // TODO Auto-generated catch block |
| + e.printStackTrace(); |
| + } |
| } |
| |
| - protected IndexReader() { |
| + protected IndexReader() { |
| refCount = 1; |
| + //TODO: find best set points |
| + try { |
| + cache = Cache.FACTORY.getCache(this); |
| + } catch (IOException e) { |
| + // TODO: how to deal with this? |
| + e.printStackTrace(); |
| + } |
| } |
| |
| /** |
| @@ -783,7 +799,57 @@
|
| hasChanges = true; |
| doUndeleteAll(); |
| } |
| + |
| + /** |
| + * Use this CacheFactory to generate a Cache for the current IndexReader. |
| + * Closes the previous cache first. |
| + */ |
| + public void useCacheFactory(CacheFactory factory) throws IOException { |
| + if (null != cache) cache.close(); |
| + cache = factory.getCache(this); |
| + } |
| |
| + /** |
| + * EXPERT: raw access to the cache for introspection |
| + */ |
| + public Cache getCache() { |
| + return cache; |
| + } |
| + |
| + /** |
| + * Generates and caches the data identified by the CacheKey, |
| + * if it is not already in the cache. |
| + */ |
| + public CacheData getCachedData(CacheKey key) throws IOException { |
| + CacheData value; |
| + synchronized (cache) { |
| + value = cache.get(key); |
| + if (value == null) { |
| + value = new CacheData(new CacheCreationPlaceholder()); |
| + cache.put(key, value); |
| + } |
| + } |
| + Object payload = value.getPayload(); |
| + if (payload instanceof CacheCreationPlaceholder) { |
| + synchronized (payload) { |
| + CacheCreationPlaceholder progress = (CacheCreationPlaceholder) payload; |
| + if (progress.value == null) { |
| + progress.value = key.buildData(this); |
| + synchronized (cache) { |
| + cache.put(key, progress.value); |
| + } |
| + } |
| + return progress.value; |
| + } |
| + } |
| + return value; |
| + } |
| + |
| + private static final class CacheCreationPlaceholder { |
| + CacheData value; |
| + } |
| + |
| + |
| /** Implements actual undeleteAll() in subclass. */ |
| protected abstract void doUndeleteAll() throws CorruptIndexException, IOException; |
| |
| @@ -830,6 +896,7 @@
|
| public final synchronized void close() throws IOException { |
| if (!closed) { |
| decRef(); |
| + if (null != cache) cache.close(); |
| closed = true; |
| } |
| } |
| Index: src/java/org/apache/lucene/index/MultiReader.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/MultiReader.java (revision 642339)
|
| +++ src/java/org/apache/lucene/index/MultiReader.java (working copy)
|
| @@ -27,6 +27,11 @@
|
| import org.apache.lucene.index.MultiSegmentReader.MultiTermDocs; |
| import org.apache.lucene.index.MultiSegmentReader.MultiTermEnum; |
| import org.apache.lucene.index.MultiSegmentReader.MultiTermPositions; |
| +import org.apache.lucene.index.cache.Cache; |
| +import org.apache.lucene.index.cache.CacheData; |
| +import org.apache.lucene.index.cache.CacheFactory; |
| +import org.apache.lucene.index.cache.CacheKey; |
| +import org.apache.lucene.index.cache.FieldValues; |
| |
| /** An IndexReader which reads multiple indexes, appending their content. |
| * |
| @@ -85,6 +90,13 @@
|
| hasDeletions = true; |
| } |
| starts[subReaders.length] = maxDoc; |
| + //TODO: find best spots for this |
| + try { |
| + useCacheFactory(Cache.FACTORY); |
| + } catch (IOException e) { |
| + // TODO: decide how to deal with this |
| + e.printStackTrace(); |
| + } |
| } |
| |
| /** |
| @@ -161,6 +173,19 @@
|
| } |
| } |
| } |
| + |
| + /** |
| + * Use this CacheFactory to generate a Cache for the current IndexReader, |
| + * as well as all of the subReaders. |
| + * |
| + * Closes the previous cache first. |
| + */ |
| + public void useCacheFactory(CacheFactory factory) throws IOException { |
| + super.useCacheFactory(factory); |
| + for (int i = 0; i < subReaders.length; i++) { |
| + subReaders[i].useCacheFactory(factory); |
| + } |
| + } |
| |
| public TermFreqVector[] getTermFreqVectors(int n) throws IOException { |
| ensureOpen(); |
| @@ -336,6 +361,48 @@
|
| } |
| } |
| |
| + /** |
| + * Generates and caches the data identified by the CacheKey, if it is not already in the cache. |
| + * |
| + * Delegates to subReaders if the CacheKey is mergeable, and then caches the merged result. |
| + */ |
| + public CacheData getCachedData(final CacheKey key) throws IOException { |
| + if( ! key.usesFieldValues()) { |
| + if ( ! key.isMergable() ) |
| + return super.getCachedData(key); |
| + |
| + CacheData[] data = new CacheData[subReaders.length]; |
| + for (int i = 0; i < subReaders.length; i++) { |
| + data[i] = subReaders[i].getCachedData(key); |
| + } |
| + |
| + return key.mergeData(starts, data); |
| + } |
| + |
| + FieldValues multiFieldValues = new FieldValues() { |
| + CacheData[] data = new CacheData[subReaders.length]; |
| + |
| + { |
| + for (int i = 0; i < subReaders.length; i++) { |
| + data[i] = subReaders[i].getCachedData(key); |
| + } |
| + } |
| + |
| + public Comparable getOrd(int doc) { |
| + int i = readerIndex(doc); // find segment num |
| + return ((FieldValues)data[i].getPayload()).getOrd(doc - starts[i]); // dispatch to segment reader |
| + } |
| + |
| + public Comparable getValue(int doc) { |
| + int i = readerIndex(doc); // find segment num |
| + return ((FieldValues)data[i].getPayload()).getValue(doc - starts[i]); // dispatch to segment reader |
| + } |
| + |
| + }; |
| + |
| + return new CacheData(multiFieldValues); |
| + } |
| + |
| public Collection getFieldNames (IndexReader.FieldOption fieldNames) { |
| ensureOpen(); |
| return MultiSegmentReader.getFieldNames(fieldNames, this.subReaders); |
| Index: src/java/org/apache/lucene/index/MultiSegmentReader.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/index/MultiSegmentReader.java (revision 642339)
|
| +++ src/java/org/apache/lucene/index/MultiSegmentReader.java (working copy)
|
| @@ -19,6 +19,9 @@
|
| |
| import org.apache.lucene.document.Document; |
| import org.apache.lucene.document.FieldSelector; |
| +import org.apache.lucene.index.cache.CacheData; |
| +import org.apache.lucene.index.cache.CacheKey; |
| +import org.apache.lucene.index.cache.FieldValues; |
| import org.apache.lucene.store.Directory; |
| |
| import java.io.IOException; |
| @@ -30,19 +33,20 @@
|
| import java.util.Map; |
| import java.util.Set; |
| |
| -/** |
| +/** |
| * An IndexReader which reads indexes with multiple segments. |
| */ |
| class MultiSegmentReader extends DirectoryIndexReader { |
| protected SegmentReader[] subReaders; |
| - private int[] starts; // 1st docno for each segment |
| + private int[] starts; // 1st docno for each segment |
| private Hashtable normsCache = new Hashtable(); |
| private int maxDoc = 0; |
| private int numDocs = -1; |
| private boolean hasDeletions = false; |
| |
| /** Construct reading the named set of readers. */ |
| - MultiSegmentReader(Directory directory, SegmentInfos sis, boolean closeDirectory) throws IOException { |
| + MultiSegmentReader(Directory directory, SegmentInfos sis, boolean closeDirectory) |
| + throws IOException { |
| super(directory, sis, closeDirectory); |
| // To reduce the chance of hitting FileNotFound |
| // (and having to retry), we open segments in |
| @@ -50,12 +54,12 @@
|
| // the newest segments first. |
| |
| SegmentReader[] readers = new SegmentReader[sis.size()]; |
| - for (int i = sis.size()-1; i >= 0; i--) { |
| + for (int i = sis.size() - 1; i >= 0; i--) { |
| try { |
| readers[i] = SegmentReader.get(sis.info(i)); |
| } catch (IOException e) { |
| // Close all readers we had opened: |
| - for(i++;i<sis.size();i++) { |
| + for (i++; i < sis.size(); i++) { |
| try { |
| readers[i].close(); |
| } catch (IOException ignore) { |
| @@ -70,9 +74,10 @@
|
| } |
| |
| /** This contructor is only used for {@link #reopen()} */ |
| - MultiSegmentReader(Directory directory, SegmentInfos infos, boolean closeDirectory, SegmentReader[] oldReaders, int[] oldStarts, Map oldNormsCache) throws IOException { |
| + MultiSegmentReader(Directory directory, SegmentInfos infos, boolean closeDirectory, |
| + SegmentReader[] oldReaders, int[] oldStarts, Map oldNormsCache) throws IOException { |
| super(directory, infos, closeDirectory); |
| - |
| + |
| // we put the old SegmentReaders in a map, that allows us |
| // to lookup a reader using its segment name |
| Map segmentReaders = new HashMap(); |
| @@ -83,14 +88,14 @@
|
| segmentReaders.put(oldReaders[i].getSegmentName(), new Integer(i)); |
| } |
| } |
| - |
| + |
| SegmentReader[] newReaders = new SegmentReader[infos.size()]; |
| - |
| + |
| // remember which readers are shared between the old and the re-opened |
| // MultiSegmentReader - we have to incRef those readers |
| boolean[] readerShared = new boolean[infos.size()]; |
| - |
| - for (int i = infos.size() - 1; i>=0; i--) { |
| + |
| + for (int i = infos.size() - 1; i >= 0; i--) { |
| // find SegmentReader for this segment |
| Integer oldReaderIndex = (Integer) segmentReaders.get(infos.info(i).name); |
| if (oldReaderIndex == null) { |
| @@ -104,7 +109,9 @@
|
| boolean success = false; |
| try { |
| SegmentReader newReader; |
| - if (newReaders[i] == null || infos.info(i).getUseCompoundFile() != newReaders[i].getSegmentInfo().getUseCompoundFile()) { |
| + if (newReaders[i] == null |
| + || infos.info(i).getUseCompoundFile() != newReaders[i].getSegmentInfo() |
| + .getUseCompoundFile()) { |
| // this is a new reader; in case we hit an exception we can close it safely |
| newReader = SegmentReader.get(infos.info(i)); |
| } else { |
| @@ -141,11 +148,11 @@
|
| } |
| } |
| } |
| - } |
| - |
| + } |
| + |
| // initialize the readers to calculate maxDoc before we try to reuse the old normsCache |
| initialize(newReaders); |
| - |
| + |
| // try to copy unchanged norms from the old normsCache to the new one |
| if (oldNormsCache != null) { |
| Iterator it = oldNormsCache.keySet().iterator(); |
| @@ -154,38 +161,81 @@
|
| if (!hasNorms(field)) { |
| continue; |
| } |
| - |
| + |
| byte[] oldBytes = (byte[]) oldNormsCache.get(field); |
| - |
| + |
| byte[] bytes = new byte[maxDoc()]; |
| - |
| + |
| for (int i = 0; i < subReaders.length; i++) { |
| Integer oldReaderIndex = ((Integer) segmentReaders.get(subReaders[i].getSegmentName())); |
| |
| - // this SegmentReader was not re-opened, we can copy all of its norms |
| - if (oldReaderIndex != null && |
| - (oldReaders[oldReaderIndex.intValue()] == subReaders[i] |
| - || oldReaders[oldReaderIndex.intValue()].norms.get(field) == subReaders[i].norms.get(field))) { |
| + // this SegmentReader was not re-opened, we can copy all of its norms |
| + if (oldReaderIndex != null |
| + && (oldReaders[oldReaderIndex.intValue()] == subReaders[i] || oldReaders[oldReaderIndex |
| + .intValue()].norms.get(field) == subReaders[i].norms.get(field))) { |
| // we don't have to synchronize here: either this constructor is called from a SegmentReader, |
| // in which case no old norms cache is present, or it is called from MultiReader.reopen(), |
| // which is synchronized |
| - System.arraycopy(oldBytes, oldStarts[oldReaderIndex.intValue()], bytes, starts[i], starts[i+1] - starts[i]); |
| + System.arraycopy(oldBytes, oldStarts[oldReaderIndex.intValue()], bytes, starts[i], |
| + starts[i + 1] - starts[i]); |
| } else { |
| subReaders[i].norms(field, bytes, starts[i]); |
| } |
| } |
| - |
| - normsCache.put(field, bytes); // update cache |
| + |
| + normsCache.put(field, bytes); // update cache |
| } |
| } |
| } |
| |
| + /** |
| + * Generates and caches the data identified by the CacheKey, if it is not already in the cache. |
| + * |
| + * Delegates to subReaders if the CacheKey is mergeable, and then caches the merged result. |
| + */ |
| + public CacheData getCachedData(final CacheKey key) throws IOException { |
| + if( ! key.usesFieldValues()) { |
| + if ( ! key.isMergable() ) |
| + return super.getCachedData(key); |
| + |
| + CacheData[] data = new CacheData[subReaders.length]; |
| + for (int i = 0; i < subReaders.length; i++) { |
| + data[i] = subReaders[i].getCachedData(key); |
| + } |
| + |
| + return key.mergeData(starts, data); |
| + } |
| + |
| + FieldValues multiFieldValues = new FieldValues() { |
| + CacheData[] data = new CacheData[subReaders.length]; |
| + |
| + { |
| + for (int i = 0; i < subReaders.length; i++) { |
| + data[i] = subReaders[i].getCachedData(key); |
| + } |
| + } |
| + |
| + public Comparable getOrd(int doc) { |
| + int i = readerIndex(doc); // find segment num |
| + return ((FieldValues)data[i].getPayload()).getOrd(doc - starts[i]); // dispatch to segment reader |
| + } |
| + |
| + public Comparable getValue(int doc) { |
| + int i = readerIndex(doc); // find segment num |
| + return ((FieldValues)data[i].getPayload()).getValue(doc - starts[i]); // dispatch to segment reader |
| + } |
| + |
| + }; |
| + |
| + return new CacheData(multiFieldValues); |
| + } |
| + |
| private void initialize(SegmentReader[] subReaders) { |
| this.subReaders = subReaders; |
| - starts = new int[subReaders.length + 1]; // build starts array |
| + starts = new int[subReaders.length + 1]; // build starts array |
| for (int i = 0; i < subReaders.length; i++) { |
| starts[i] = maxDoc; |
| - maxDoc += subReaders[i].maxDoc(); // compute maxDocs |
| + maxDoc += subReaders[i].maxDoc(); // compute maxDocs |
| |
| if (subReaders[i].hasDeletions()) |
| hasDeletions = true; |
| @@ -193,53 +243,54 @@
|
| starts[subReaders.length] = maxDoc; |
| } |
| |
| - protected synchronized DirectoryIndexReader doReopen(SegmentInfos infos) throws CorruptIndexException, IOException { |
| + protected synchronized DirectoryIndexReader doReopen(SegmentInfos infos) |
| + throws CorruptIndexException, IOException { |
| if (infos.size() == 1) { |
| // The index has only one segment now, so we can't refresh the MultiSegmentReader. |
| // Return a new SegmentReader instead |
| SegmentReader newReader = SegmentReader.get(infos, infos.info(0), false); |
| return newReader; |
| } else { |
| - return new MultiSegmentReader(directory, infos, closeDirectory, subReaders, starts, normsCache); |
| - } |
| + return new MultiSegmentReader(directory, infos, closeDirectory, subReaders, starts, |
| + normsCache); |
| + } |
| } |
| |
| public TermFreqVector[] getTermFreqVectors(int n) throws IOException { |
| ensureOpen(); |
| - int i = readerIndex(n); // find segment num |
| + int i = readerIndex(n); // find segment num |
| return subReaders[i].getTermFreqVectors(n - starts[i]); // dispatch to segment |
| } |
| |
| - public TermFreqVector getTermFreqVector(int n, String field) |
| - throws IOException { |
| + public TermFreqVector getTermFreqVector(int n, String field) throws IOException { |
| ensureOpen(); |
| - int i = readerIndex(n); // find segment num |
| + int i = readerIndex(n); // find segment num |
| return subReaders[i].getTermFreqVector(n - starts[i], field); |
| } |
| |
| - |
| - public void getTermFreqVector(int docNumber, String field, TermVectorMapper mapper) throws IOException { |
| + public void getTermFreqVector(int docNumber, String field, TermVectorMapper mapper) |
| + throws IOException { |
| ensureOpen(); |
| - int i = readerIndex(docNumber); // find segment num |
| + int i = readerIndex(docNumber); // find segment num |
| subReaders[i].getTermFreqVector(docNumber - starts[i], field, mapper); |
| } |
| |
| public void getTermFreqVector(int docNumber, TermVectorMapper mapper) throws IOException { |
| ensureOpen(); |
| - int i = readerIndex(docNumber); // find segment num |
| + int i = readerIndex(docNumber); // find segment num |
| subReaders[i].getTermFreqVector(docNumber - starts[i], mapper); |
| } |
| |
| public boolean isOptimized() { |
| return false; |
| } |
| - |
| + |
| public synchronized int numDocs() { |
| // Don't call ensureOpen() here (it could affect performance) |
| - if (numDocs == -1) { // check cache |
| - int n = 0; // cache miss--recompute |
| + if (numDocs == -1) { // check cache |
| + int n = 0; // cache miss--recompute |
| for (int i = 0; i < subReaders.length; i++) |
| - n += subReaders[i].numDocs(); // sum from readers |
| + n += subReaders[i].numDocs(); // sum from readers |
| numDocs = n; |
| } |
| return numDocs; |
| @@ -251,16 +302,17 @@
|
| } |
| |
| // inherit javadoc |
| - public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { |
| + public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, |
| + IOException { |
| ensureOpen(); |
| - int i = readerIndex(n); // find segment num |
| - return subReaders[i].document(n - starts[i], fieldSelector); // dispatch to segment reader |
| + int i = readerIndex(n); // find segment num |
| + return subReaders[i].document(n - starts[i], fieldSelector); // dispatch to segment reader |
| } |
| |
| public boolean isDeleted(int n) { |
| // Don't call ensureOpen() here (it could affect performance) |
| - int i = readerIndex(n); // find segment num |
| - return subReaders[i].isDeleted(n - starts[i]); // dispatch to segment reader |
| + int i = readerIndex(n); // find segment num |
| + return subReaders[i].isDeleted(n - starts[i]); // dispatch to segment reader |
| } |
| |
| public boolean hasDeletions() { |
| @@ -269,9 +321,9 @@
|
| } |
| |
| protected void doDelete(int n) throws CorruptIndexException, IOException { |
| - numDocs = -1; // invalidate cache |
| - int i = readerIndex(n); // find segment num |
| - subReaders[i].deleteDocument(n - starts[i]); // dispatch to segment reader |
| + numDocs = -1; // invalidate cache |
| + int i = readerIndex(n); // find segment num |
| + subReaders[i].deleteDocument(n - starts[i]); // dispatch to segment reader |
| hasDeletions = true; |
| } |
| |
| @@ -280,17 +332,17 @@
|
| subReaders[i].undeleteAll(); |
| |
| hasDeletions = false; |
| - numDocs = -1; // invalidate cache |
| + numDocs = -1; // invalidate cache |
| } |
| |
| - private int readerIndex(int n) { // find reader for doc n: |
| + private int readerIndex(int n) { // find reader for doc n: |
| return readerIndex(n, this.starts, this.subReaders.length); |
| } |
| - |
| - static int readerIndex(int n, int[] starts, int numSubReaders) { // find reader for doc n: |
| - int lo = 0; // search starts array |
| - int hi = numSubReaders - 1; // for first element less |
| |
| + static int readerIndex(int n, int[] starts, int numSubReaders) { // find reader for doc n: |
| + int lo = 0; // search starts array |
| + int hi = numSubReaders - 1; // for first element less |
| + |
| while (hi >= lo) { |
| int mid = (lo + hi) >> 1; |
| int midValue = starts[mid]; |
| @@ -298,9 +350,9 @@
|
| hi = mid - 1; |
| else if (n > midValue) |
| lo = mid + 1; |
| - else { // found a match |
| - while (mid+1 < numSubReaders && starts[mid+1] == midValue) { |
| - mid++; // scan to last match |
| + else { // found a match |
| + while (mid + 1 < numSubReaders && starts[mid + 1] == midValue) { |
| + mid++; // scan to last match |
| } |
| return mid; |
| } |
| @@ -311,49 +363,53 @@
|
| public boolean hasNorms(String field) throws IOException { |
| ensureOpen(); |
| for (int i = 0; i < subReaders.length; i++) { |
| - if (subReaders[i].hasNorms(field)) return true; |
| + if (subReaders[i].hasNorms(field)) |
| + return true; |
| } |
| return false; |
| } |
| |
| private byte[] ones; |
| + |
| private byte[] fakeNorms() { |
| - if (ones==null) ones=SegmentReader.createFakeNorms(maxDoc()); |
| + if (ones == null) |
| + ones = SegmentReader.createFakeNorms(maxDoc()); |
| return ones; |
| } |
| |
| public synchronized byte[] norms(String field) throws IOException { |
| ensureOpen(); |
| - byte[] bytes = (byte[])normsCache.get(field); |
| + byte[] bytes = (byte[]) normsCache.get(field); |
| if (bytes != null) |
| - return bytes; // cache hit |
| + return bytes; // cache hit |
| if (!hasNorms(field)) |
| return fakeNorms(); |
| |
| bytes = new byte[maxDoc()]; |
| for (int i = 0; i < subReaders.length; i++) |
| subReaders[i].norms(field, bytes, starts[i]); |
| - normsCache.put(field, bytes); // update cache |
| + normsCache.put(field, bytes); // update cache |
| return bytes; |
| } |
| |
| - public synchronized void norms(String field, byte[] result, int offset) |
| - throws IOException { |
| + public synchronized void norms(String field, byte[] result, int offset) throws IOException { |
| ensureOpen(); |
| - byte[] bytes = (byte[])normsCache.get(field); |
| - if (bytes==null && !hasNorms(field)) bytes=fakeNorms(); |
| - if (bytes != null) // cache hit |
| + byte[] bytes = (byte[]) normsCache.get(field); |
| + if (bytes == null && !hasNorms(field)) |
| + bytes = fakeNorms(); |
| + if (bytes != null) // cache hit |
| System.arraycopy(bytes, 0, result, offset, maxDoc()); |
| |
| - for (int i = 0; i < subReaders.length; i++) // read from segments |
| + for (int i = 0; i < subReaders.length; i++) |
| + // read from segments |
| subReaders[i].norms(field, result, offset + starts[i]); |
| } |
| |
| - protected void doSetNorm(int n, String field, byte value) |
| - throws CorruptIndexException, IOException { |
| - normsCache.remove(field); // clear cache |
| - int i = readerIndex(n); // find segment num |
| - subReaders[i].setNorm(n-starts[i], field, value); // dispatch |
| + protected void doSetNorm(int n, String field, byte value) throws CorruptIndexException, |
| + IOException { |
| + normsCache.remove(field); // clear cache |
| + int i = readerIndex(n); // find segment num |
| + subReaders[i].setNorm(n - starts[i], field, value); // dispatch |
| } |
| |
| public TermEnum terms() throws IOException { |
| @@ -368,7 +424,7 @@
|
| |
| public int docFreq(Term t) throws IOException { |
| ensureOpen(); |
| - int total = 0; // sum freqs in segments |
| + int total = 0; // sum freqs in segments |
| for (int i = 0; i < subReaders.length; i++) |
| total += subReaders[i].docFreq(t); |
| return total; |
| @@ -406,17 +462,17 @@
|
| protected synchronized void doClose() throws IOException { |
| for (int i = 0; i < subReaders.length; i++) |
| subReaders[i].decRef(); |
| - |
| + |
| // maybe close directory |
| super.doClose(); |
| } |
| |
| - public Collection getFieldNames (IndexReader.FieldOption fieldNames) { |
| + public Collection getFieldNames(IndexReader.FieldOption fieldNames) { |
| ensureOpen(); |
| return getFieldNames(fieldNames, this.subReaders); |
| } |
| - |
| - static Collection getFieldNames (IndexReader.FieldOption fieldNames, IndexReader[] subReaders) { |
| + |
| + static Collection getFieldNames(IndexReader.FieldOption fieldNames, IndexReader[] subReaders) { |
| // maintain a unique set of field names |
| Set fieldSet = new HashSet(); |
| for (int i = 0; i < subReaders.length; i++) { |
| @@ -425,8 +481,8 @@
|
| fieldSet.addAll(names); |
| } |
| return fieldSet; |
| - } |
| - |
| + } |
| + |
| // for testing |
| SegmentReader[] getSubReaders() { |
| return subReaders; |
| @@ -446,64 +502,63 @@
|
| |
| static class MultiTermEnum extends TermEnum { |
| private SegmentMergeQueue queue; |
| - |
| + |
| private Term term; |
| private int docFreq; |
| - |
| - public MultiTermEnum(IndexReader[] readers, int[] starts, Term t) |
| - throws IOException { |
| + |
| + public MultiTermEnum(IndexReader[] readers, int[] starts, Term t) throws IOException { |
| queue = new SegmentMergeQueue(readers.length); |
| for (int i = 0; i < readers.length; i++) { |
| IndexReader reader = readers[i]; |
| TermEnum termEnum; |
| - |
| + |
| if (t != null) { |
| termEnum = reader.terms(t); |
| } else |
| termEnum = reader.terms(); |
| - |
| + |
| SegmentMergeInfo smi = new SegmentMergeInfo(starts[i], termEnum, reader); |
| if (t == null ? smi.next() : termEnum.term() != null) |
| - queue.put(smi); // initialize queue |
| + queue.put(smi); // initialize queue |
| else |
| smi.close(); |
| } |
| - |
| + |
| if (t != null && queue.size() > 0) { |
| next(); |
| } |
| } |
| - |
| + |
| public boolean next() throws IOException { |
| - SegmentMergeInfo top = (SegmentMergeInfo)queue.top(); |
| + SegmentMergeInfo top = (SegmentMergeInfo) queue.top(); |
| if (top == null) { |
| term = null; |
| return false; |
| } |
| - |
| + |
| term = top.term; |
| docFreq = 0; |
| - |
| + |
| while (top != null && term.compareTo(top.term) == 0) { |
| queue.pop(); |
| - docFreq += top.termEnum.docFreq(); // increment freq |
| + docFreq += top.termEnum.docFreq(); // increment freq |
| if (top.next()) |
| - queue.put(top); // restore queue |
| + queue.put(top); // restore queue |
| else |
| - top.close(); // done with a segment |
| - top = (SegmentMergeInfo)queue.top(); |
| + top.close(); // done with a segment |
| + top = (SegmentMergeInfo) queue.top(); |
| } |
| return true; |
| } |
| - |
| + |
| public Term term() { |
| return term; |
| } |
| - |
| + |
| public int docFreq() { |
| return docFreq; |
| } |
| - |
| + |
| public void close() throws IOException { |
| queue.close(); |
| } |
| @@ -513,44 +568,44 @@
|
| protected IndexReader[] readers; |
| protected int[] starts; |
| protected Term term; |
| - |
| + |
| protected int base = 0; |
| protected int pointer = 0; |
| - |
| + |
| private TermDocs[] readerTermDocs; |
| - protected TermDocs current; // == readerTermDocs[pointer] |
| - |
| + protected TermDocs current; // == readerTermDocs[pointer] |
| + |
| public MultiTermDocs(IndexReader[] r, int[] s) { |
| readers = r; |
| starts = s; |
| - |
| + |
| readerTermDocs = new TermDocs[r.length]; |
| } |
| - |
| + |
| public int doc() { |
| return base + current.doc(); |
| } |
| + |
| public int freq() { |
| return current.freq(); |
| } |
| - |
| + |
| public void seek(Term term) { |
| this.term = term; |
| this.base = 0; |
| this.pointer = 0; |
| this.current = null; |
| } |
| - |
| + |
| public void seek(TermEnum termEnum) throws IOException { |
| seek(termEnum.term()); |
| } |
| - |
| + |
| public boolean next() throws IOException { |
| - for(;;) { |
| - if (current!=null && current.next()) { |
| + for (;;) { |
| + if (current != null && current.next()) { |
| return true; |
| - } |
| - else if (pointer < readers.length) { |
| + } else if (pointer < readers.length) { |
| base = starts[pointer]; |
| current = termDocs(pointer++); |
| } else { |
| @@ -558,12 +613,12 @@
|
| } |
| } |
| } |
| - |
| + |
| /** Optimized implementation. */ |
| public int read(final int[] docs, final int[] freqs) throws IOException { |
| while (true) { |
| while (current == null) { |
| - if (pointer < readers.length) { // try next segment |
| + if (pointer < readers.length) { // try next segment |
| base = starts[pointer]; |
| current = termDocs(pointer++); |
| } else { |
| @@ -571,21 +626,21 @@
|
| } |
| } |
| int end = current.read(docs, freqs); |
| - if (end == 0) { // none left in segment |
| + if (end == 0) { // none left in segment |
| current = null; |
| - } else { // got some |
| - final int b = base; // adjust doc numbers |
| + } else { // got some |
| + final int b = base; // adjust doc numbers |
| for (int i = 0; i < end; i++) |
| - docs[i] += b; |
| + docs[i] += b; |
| return end; |
| } |
| } |
| } |
| - |
| - /* A Possible future optimization could skip entire segments */ |
| + |
| + /* A Possible future optimization could skip entire segments */ |
| public boolean skipTo(int target) throws IOException { |
| - for(;;) { |
| - if (current != null && current.skipTo(target-base)) { |
| + for (;;) { |
| + if (current != null && current.skipTo(target - base)) { |
| return true; |
| } else if (pointer < readers.length) { |
| base = starts[pointer]; |
| @@ -594,7 +649,7 @@
|
| return false; |
| } |
| } |
| - |
| + |
| private TermDocs termDocs(int i) throws IOException { |
| if (term == null) |
| return null; |
| @@ -604,12 +659,11 @@
|
| result.seek(term); |
| return result; |
| } |
| - |
| - protected TermDocs termDocs(IndexReader reader) |
| - throws IOException { |
| + |
| + protected TermDocs termDocs(IndexReader reader) throws IOException { |
| return reader.termDocs(); |
| } |
| - |
| + |
| public void close() throws IOException { |
| for (int i = 0; i < readerTermDocs.length; i++) { |
| if (readerTermDocs[i] != null) |
| @@ -620,26 +674,25 @@
|
| |
| static class MultiTermPositions extends MultiTermDocs implements TermPositions { |
| public MultiTermPositions(IndexReader[] r, int[] s) { |
| - super(r,s); |
| + super(r, s); |
| } |
| - |
| + |
| protected TermDocs termDocs(IndexReader reader) throws IOException { |
| - return (TermDocs)reader.termPositions(); |
| + return (TermDocs) reader.termPositions(); |
| } |
| - |
| + |
| public int nextPosition() throws IOException { |
| - return ((TermPositions)current).nextPosition(); |
| + return ((TermPositions) current).nextPosition(); |
| } |
| - |
| + |
| public int getPayloadLength() { |
| - return ((TermPositions)current).getPayloadLength(); |
| + return ((TermPositions) current).getPayloadLength(); |
| } |
| - |
| + |
| public byte[] getPayload(byte[] data, int offset) throws IOException { |
| - return ((TermPositions)current).getPayload(data, offset); |
| + return ((TermPositions) current).getPayload(data, offset); |
| } |
| - |
| - |
| + |
| // TODO: Remove warning after API has been finalized |
| public boolean isPayloadAvailable() { |
| return ((TermPositions) current).isPayloadAvailable(); |
| Index: src/java/org/apache/lucene/search/ExtendedFieldCache.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/ExtendedFieldCache.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/ExtendedFieldCache.java (working copy)
|
| @@ -1,29 +1,23 @@
|
| package org.apache.lucene.search; |
| |
| -import org.apache.lucene.index.IndexReader; |
| - |
| import java.io.IOException; |
| |
| +import org.apache.lucene.index.IndexReader; |
| +import org.apache.lucene.index.cache.DoubleArrayCacheKey; |
| +import org.apache.lucene.index.cache.LongArrayCacheKey; |
| |
| + |
| /** |
| * |
| - * |
| + * @deprecated use IndexReader.getCachedData |
| **/ |
| public interface ExtendedFieldCache extends FieldCache { |
| - public interface LongParser { |
| - /** |
| - * Return an long representation of this field's value. |
| - */ |
| - public long parseLong(String string); |
| - } |
| + public interface LongParser extends LongArrayCacheKey.LongParser { } |
| + public interface DoubleParser extends DoubleArrayCacheKey.DoubleParser { } |
| |
| - public interface DoubleParser { |
| - /** |
| - * Return an long representation of this field's value. |
| - */ |
| - public double parseDouble(String string); |
| - } |
| - |
| + /** |
| + * @deprecated |
| + **/ |
| public static ExtendedFieldCache EXT_DEFAULT = new ExtendedFieldCacheImpl(); |
| |
| /** |
| @@ -36,6 +30,7 @@
|
| * @param field Which field contains the longs. |
| * @return The values in the given field for each document. |
| * @throws java.io.IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new LongArrayCacheKey(field)) |
| */ |
| public long[] getLongs(IndexReader reader, String field) |
| throws IOException; |
| @@ -51,6 +46,7 @@
|
| * @param parser Computes integer for string values. |
| * @return The values in the given field for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new LongArrayCacheKey(field), parser) |
| */ |
| public long[] getLongs(IndexReader reader, String field, LongParser parser) |
| throws IOException; |
| @@ -66,6 +62,7 @@
|
| * @param field Which field contains the doubles. |
| * @return The values in the given field for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new DoubleArrayCacheKey(field)) |
| */ |
| public double[] getDoubles(IndexReader reader, String field) |
| throws IOException; |
| @@ -81,6 +78,7 @@
|
| * @param parser Computes integer for string values. |
| * @return The values in the given field for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new DoubleArrayCacheKey(field), parser) |
| */ |
| public double[] getDoubles(IndexReader reader, String field, DoubleParser parser) |
| throws IOException; |
| Index: src/java/org/apache/lucene/search/ExtendedFieldCacheImpl.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/ExtendedFieldCacheImpl.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/ExtendedFieldCacheImpl.java (working copy)
|
| @@ -1,28 +1,27 @@
|
| package org.apache.lucene.search; |
| |
| import org.apache.lucene.index.IndexReader; |
| -import org.apache.lucene.index.Term; |
| -import org.apache.lucene.index.TermDocs; |
| -import org.apache.lucene.index.TermEnum; |
| +import org.apache.lucene.index.cache.CacheKey; |
| +import org.apache.lucene.index.cache.DoubleArrayCacheKey; |
| +import org.apache.lucene.index.cache.LongArrayCacheKey; |
| |
| import java.io.IOException; |
| |
| |
| /** |
| - * |
| - * |
| + * @deprecated use IndexReader.getCachedData |
| **/ |
| class ExtendedFieldCacheImpl extends FieldCacheImpl implements ExtendedFieldCache { |
| private static final LongParser LONG_PARSER = new LongParser() { |
| - public long parseLong(String value) { |
| - return Long.parseLong(value); |
| - } |
| + public long parseLong(String value) { |
| + return Long.parseLong(value); |
| + } |
| }; |
| |
| private static final DoubleParser DOUBLE_PARSER = new DoubleParser() { |
| - public double parseDouble(String value) { |
| - return Double.parseDouble(value); |
| - } |
| + public double parseDouble(String value) { |
| + return Double.parseDouble(value); |
| + } |
| }; |
| |
| |
| @@ -33,37 +32,10 @@
|
| // inherit javadocs |
| public long[] getLongs(IndexReader reader, String field, LongParser parser) |
| throws IOException { |
| - return (long[]) longsCache.get(reader, new Entry(field, parser)); |
| + return (long[]) reader.getCachedData |
| + (new LongArrayCacheKey(field, parser)).getPayload(); |
| } |
| |
| - Cache longsCache = new Cache() { |
| - |
| - protected Object createValue(IndexReader reader, Object entryKey) |
| - throws IOException { |
| - Entry entry = (Entry) entryKey; |
| - String field = entry.field; |
| - LongParser parser = (LongParser) entry.custom; |
| - final long[] retArray = new long[reader.maxDoc()]; |
| - TermDocs termDocs = reader.termDocs(); |
| - TermEnum termEnum = reader.terms (new Term(field, "")); |
| - try { |
| - do { |
| - Term term = termEnum.term(); |
| - if (term==null || term.field() != field) break; |
| - long termval = parser.parseLong(term.text()); |
| - termDocs.seek (termEnum); |
| - while (termDocs.next()) { |
| - retArray[termDocs.doc()] = termval; |
| - } |
| - } while (termEnum.next()); |
| - } finally { |
| - termDocs.close(); |
| - termEnum.close(); |
| - } |
| - return retArray; |
| - } |
| - }; |
| - |
| // inherit javadocs |
| public double[] getDoubles(IndexReader reader, String field) |
| throws IOException { |
| @@ -73,93 +45,14 @@
|
| // inherit javadocs |
| public double[] getDoubles(IndexReader reader, String field, DoubleParser parser) |
| throws IOException { |
| - return (double[]) doublesCache.get(reader, new Entry(field, parser)); |
| + return (double[]) reader.getCachedData |
| + (new DoubleArrayCacheKey(field, parser)).getPayload(); |
| } |
| |
| - Cache doublesCache = new Cache() { |
| |
| - protected Object createValue(IndexReader reader, Object entryKey) |
| - throws IOException { |
| - Entry entry = (Entry) entryKey; |
| - String field = entry.field; |
| - DoubleParser parser = (DoubleParser) entry.custom; |
| - final double[] retArray = new double[reader.maxDoc()]; |
| - TermDocs termDocs = reader.termDocs(); |
| - TermEnum termEnum = reader.terms (new Term (field, "")); |
| - try { |
| - do { |
| - Term term = termEnum.term(); |
| - if (term==null || term.field() != field) break; |
| - double termval = parser.parseDouble(term.text()); |
| - termDocs.seek (termEnum); |
| - while (termDocs.next()) { |
| - retArray[termDocs.doc()] = termval; |
| - } |
| - } while (termEnum.next()); |
| - } finally { |
| - termDocs.close(); |
| - termEnum.close(); |
| - } |
| - return retArray; |
| - } |
| - }; |
| - |
| - |
| // inherit javadocs |
| public Object getAuto(IndexReader reader, String field) throws IOException { |
| - return autoCache.get(reader, field); |
| + return CacheKey.getAutoCacheKey(reader, field); |
| } |
| |
| - Cache autoCache = new Cache() { |
| - |
| - protected Object createValue(IndexReader reader, Object fieldKey) |
| - throws IOException { |
| - String field = ((String)fieldKey).intern(); |
| - TermEnum enumerator = reader.terms (new Term (field, "")); |
| - try { |
| - Term term = enumerator.term(); |
| - if (term == null) { |
| - throw new RuntimeException ("no terms in field " + field + " - cannot determine sort type"); |
| - } |
| - Object ret = null; |
| - if (term.field() == field) { |
| - String termtext = term.text().trim(); |
| - |
| - /** |
| - * Java 1.4 level code: |
| - |
| - if (pIntegers.matcher(termtext).matches()) |
| - return IntegerSortedHitQueue.comparator (reader, enumerator, field); |
| - |
| - else if (pFloats.matcher(termtext).matches()) |
| - return FloatSortedHitQueue.comparator (reader, enumerator, field); |
| - */ |
| - |
| - // Java 1.3 level code: |
| - try { |
| - Integer.parseInt (termtext); |
| - ret = getInts (reader, field); |
| - } catch (NumberFormatException nfe1) { |
| - try { |
| - Long.parseLong(termtext); |
| - ret = getLongs (reader, field); |
| - } catch (NumberFormatException nfe2) { |
| - try { |
| - Float.parseFloat (termtext); |
| - ret = getFloats (reader, field); |
| - } catch (NumberFormatException nfe3) { |
| - ret = getStringIndex (reader, field); |
| - } |
| - } |
| - } |
| - } else { |
| - throw new RuntimeException ("field \"" + field + "\" does not appear to be indexed"); |
| - } |
| - return ret; |
| - } finally { |
| - enumerator.close(); |
| - } |
| - } |
| - }; |
| - |
| } |
| Index: src/java/org/apache/lucene/search/FieldCache.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/FieldCache.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/FieldCache.java (working copy)
|
| @@ -18,6 +18,7 @@
|
| */ |
| |
| import org.apache.lucene.index.IndexReader; |
| +import org.apache.lucene.index.cache.*; |
| import java.io.IOException; |
| |
| /** |
| @@ -28,6 +29,7 @@
|
| * @author Tim Jones (Nacimiento Software) |
| * @since lucene 1.4 |
| * @version $Id$ |
| + * @deprecated use IndexReader.getCachedData |
| */ |
| public interface FieldCache { |
| |
| @@ -37,53 +39,38 @@
|
| public static final int STRING_INDEX = -1; |
| |
| |
| - /** Expert: Stores term text values and document ordering data. */ |
| - public static class StringIndex { |
| - |
| - /** All the term values, in natural order. */ |
| - public final String[] lookup; |
| - |
| - /** For each document, an index into the lookup array. */ |
| - public final int[] order; |
| - |
| - /** Creates one of these objects */ |
| + /** Expert: Stores term text values and document ordering data. |
| + * @deprecated use StringIndexCacheKey.StringIndex |
| + */ |
| + public static class StringIndex extends StringIndexCacheKey.StringIndex { |
| public StringIndex (int[] values, String[] lookup) { |
| - this.order = values; |
| - this.lookup = lookup; |
| - } |
| + super(values,lookup); |
| + } |
| } |
| |
| /** Interface to parse bytes from document fields. |
| * @see FieldCache#getBytes(IndexReader, String, FieldCache.ByteParser) |
| + * @deprecated use ByteArrayCacheKey.ByteParser |
| */ |
| - public interface ByteParser { |
| - /** Return a single Byte representation of this field's value. */ |
| - public byte parseByte(String string); |
| - } |
| + public interface ByteParser extends ByteArrayCacheKey.ByteParser { } |
| |
| /** Interface to parse shorts from document fields. |
| * @see FieldCache#getShorts(IndexReader, String, FieldCache.ShortParser) |
| + * @deprecated use IntArrayCacheKey.ShortParser |
| */ |
| - public interface ShortParser { |
| - /** Return a short representation of this field's value. */ |
| - public short parseShort(String string); |
| - } |
| + public interface ShortParser extends ShortArrayCacheKey.ShortParser { } |
| |
| /** Interface to parse ints from document fields. |
| * @see FieldCache#getInts(IndexReader, String, FieldCache.IntParser) |
| + * @deprecated use IntArrayCacheKey.IntParser |
| */ |
| - public interface IntParser { |
| - /** Return an integer representation of this field's value. */ |
| - public int parseInt(String string); |
| - } |
| + public interface IntParser extends IntArrayCacheKey.IntParser { } |
| |
| /** Interface to parse floats from document fields. |
| * @see FieldCache#getFloats(IndexReader, String, FieldCache.FloatParser) |
| + * @deprecated use FloatArrayCacheKey.FloatParser |
| */ |
| - public interface FloatParser { |
| - /** Return an float representation of this field's value. */ |
| - public float parseFloat(String string); |
| - } |
| + public interface FloatParser extends FloatArrayCacheKey.FloatParser { } |
| |
| /** Expert: The cache used internally by sorting and range query classes. */ |
| public static FieldCache DEFAULT = new FieldCacheImpl(); |
| @@ -96,6 +83,7 @@
|
| * @param field Which field contains the single byte values. |
| * @return The values in the given field for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new ByteArrayCacheKey(field)) |
| */ |
| public byte[] getBytes (IndexReader reader, String field) |
| throws IOException; |
| @@ -109,6 +97,7 @@
|
| * @param parser Computes byte for string values. |
| * @return The values in the given field for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new ByteArrayCacheKey(field), parser) |
| */ |
| public byte[] getBytes (IndexReader reader, String field, ByteParser parser) |
| throws IOException; |
| @@ -121,6 +110,7 @@
|
| * @param field Which field contains the shorts. |
| * @return The values in the given field for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new ShortArrayCacheKey(field)) |
| */ |
| public short[] getShorts (IndexReader reader, String field) |
| throws IOException; |
| @@ -134,6 +124,7 @@
|
| * @param parser Computes short for string values. |
| * @return The values in the given field for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new ShortArrayCacheKey(field), parser) |
| */ |
| public short[] getShorts (IndexReader reader, String field, ShortParser parser) |
| throws IOException; |
| @@ -146,6 +137,7 @@
|
| * @param field Which field contains the integers. |
| * @return The values in the given field for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new IntArrayCacheKey(field)) |
| */ |
| public int[] getInts (IndexReader reader, String field) |
| throws IOException; |
| @@ -159,6 +151,7 @@
|
| * @param parser Computes integer for string values. |
| * @return The values in the given field for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new IntArrayCacheKey(field), parser) |
| */ |
| public int[] getInts (IndexReader reader, String field, IntParser parser) |
| throws IOException; |
| @@ -171,6 +164,7 @@
|
| * @param field Which field contains the floats. |
| * @return The values in the given field for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new FloatArrayCacheKey(field)) |
| */ |
| public float[] getFloats (IndexReader reader, String field) |
| throws IOException; |
| @@ -184,6 +178,7 @@
|
| * @param parser Computes float for string values. |
| * @return The values in the given field for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new FloatArrayCacheKey(field), parser) |
| */ |
| public float[] getFloats (IndexReader reader, String field, |
| FloatParser parser) throws IOException; |
| @@ -196,6 +191,7 @@
|
| * @param field Which field contains the strings. |
| * @return The values in the given field for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new StringArrayCacheKey(field)) |
| */ |
| public String[] getStrings (IndexReader reader, String field) |
| throws IOException; |
| @@ -208,6 +204,7 @@
|
| * @param field Which field contains the strings. |
| * @return Array of terms and index into the array for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCachedData(reader, new StringIndexArrayCacheKey(field)) |
| */ |
| public StringIndex getStringIndex (IndexReader reader, String field) |
| throws IOException; |
| @@ -222,6 +219,7 @@
|
| * @param field Which field contains the values. |
| * @return int[], float[] or StringIndex. |
| * @throws IOException If any error occurs. |
| + * @deprecated use CachKey.getAuto(reader, field) |
| */ |
| public Object getAuto (IndexReader reader, String field) |
| throws IOException; |
| @@ -236,6 +234,7 @@
|
| * @param comparator Used to convert terms into something to sort by. |
| * @return Array of sort objects, one for each document. |
| * @throws IOException If any error occurs. |
| + * @deprecated use IndexReader.getCacheData with a custom CacheKey |
| */ |
| public Comparable[] getCustom (IndexReader reader, String field, SortComparator comparator) |
| throws IOException; |
| Index: src/java/org/apache/lucene/search/FieldCacheImpl.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/FieldCacheImpl.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/FieldCacheImpl.java (working copy)
|
| @@ -17,17 +17,24 @@
|
| * limitations under the License. |
| */ |
| |
| -import org.apache.lucene.index.IndexReader; |
| -import org.apache.lucene.index.Term; |
| -import org.apache.lucene.index.TermDocs; |
| -import org.apache.lucene.index.TermEnum; |
| - |
| import java.io.IOException; |
| import java.util.HashMap; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.WeakHashMap; |
| |
| +import org.apache.lucene.index.IndexReader; |
| +import org.apache.lucene.index.Term; |
| +import org.apache.lucene.index.TermEnum; |
| +import org.apache.lucene.index.cache.ByteArrayCacheKey; |
| +import org.apache.lucene.index.cache.CacheKey; |
| +import org.apache.lucene.index.cache.FloatArrayCacheKey; |
| +import org.apache.lucene.index.cache.IntArrayCacheKey; |
| +import org.apache.lucene.index.cache.LongArrayCacheKey; |
| +import org.apache.lucene.index.cache.ShortArrayCacheKey; |
| +import org.apache.lucene.index.cache.StringArrayCacheKey; |
| +import org.apache.lucene.index.cache.StringIndexCacheKey; |
| + |
| /** |
| * Expert: The default cache implementation, storing all values in memory. |
| * A WeakHashMap is used for storage. |
| @@ -37,6 +44,7 @@
|
| * @author Tim Jones (Nacimiento Software) |
| * @since lucene 1.4 |
| * @version $Id$ |
| + * @deprecated use IndexReader.getCachedData |
| */ |
| class FieldCacheImpl |
| implements FieldCache { |
| @@ -81,11 +89,14 @@
|
| } |
| } |
| |
| + /** @deprecated */ |
| static final class CreationPlaceholder { |
| Object value; |
| } |
| |
| - /** Expert: Every composite-key in the internal cache is of this type. */ |
| + /** Expert: Every composite-key in the internal cache is of this type. |
| + * @deprecated |
| + */ |
| static class Entry { |
| final String field; // which Fieldable |
| final int type; // which SortField type |
| @@ -155,6 +166,7 @@
|
| return Float.parseFloat(value); |
| } |
| }; |
| + |
| |
| // inherit javadocs |
| public byte[] getBytes (IndexReader reader, String field) throws IOException { |
| @@ -164,348 +176,119 @@
|
| // inherit javadocs |
| public byte[] getBytes(IndexReader reader, String field, ByteParser parser) |
| throws IOException { |
| - return (byte[]) bytesCache.get(reader, new Entry(field, parser)); |
| + return (byte[]) reader.getCachedData |
| + (new ByteArrayCacheKey(field, parser)).getPayload(); |
| } |
| - |
| - Cache bytesCache = new Cache() { |
| - |
| - protected Object createValue(IndexReader reader, Object entryKey) |
| - throws IOException { |
| - Entry entry = (Entry) entryKey; |
| - String field = entry.field; |
| - ByteParser parser = (ByteParser) entry.custom; |
| - final byte[] retArray = new byte[reader.maxDoc()]; |
| - TermDocs termDocs = reader.termDocs(); |
| - TermEnum termEnum = reader.terms (new Term (field, "")); |
| - try { |
| - do { |
| - Term term = termEnum.term(); |
| - if (term==null || term.field() != field) break; |
| - byte termval = parser.parseByte(term.text()); |
| - termDocs.seek (termEnum); |
| - while (termDocs.next()) { |
| - retArray[termDocs.doc()] = termval; |
| - } |
| - } while (termEnum.next()); |
| - } finally { |
| - termDocs.close(); |
| - termEnum.close(); |
| - } |
| - return retArray; |
| - } |
| - }; |
| |
| // inherit javadocs |
| public short[] getShorts (IndexReader reader, String field) throws IOException { |
| - return getShorts(reader, field, SHORT_PARSER); |
| + return getShorts(reader, field, null); |
| } |
| |
| // inherit javadocs |
| public short[] getShorts(IndexReader reader, String field, ShortParser parser) |
| throws IOException { |
| - return (short[]) shortsCache.get(reader, new Entry(field, parser)); |
| + return (short[]) reader.getCachedData |
| + (new ShortArrayCacheKey(field, parser)).getPayload(); |
| } |
| |
| - Cache shortsCache = new Cache() { |
| |
| - protected Object createValue(IndexReader reader, Object entryKey) |
| - throws IOException { |
| - Entry entry = (Entry) entryKey; |
| - String field = entry.field; |
| - ShortParser parser = (ShortParser) entry.custom; |
| - final short[] retArray = new short[reader.maxDoc()]; |
| - TermDocs termDocs = reader.termDocs(); |
| - TermEnum termEnum = reader.terms (new Term (field, "")); |
| - try { |
| - do { |
| - Term term = termEnum.term(); |
| - if (term==null || term.field() != field) break; |
| - short termval = parser.parseShort(term.text()); |
| - termDocs.seek (termEnum); |
| - while (termDocs.next()) { |
| - retArray[termDocs.doc()] = termval; |
| - } |
| - } while (termEnum.next()); |
| - } finally { |
| - termDocs.close(); |
| - termEnum.close(); |
| - } |
| - return retArray; |
| - } |
| - }; |
| |
| // inherit javadocs |
| public int[] getInts (IndexReader reader, String field) throws IOException { |
| - return getInts(reader, field, INT_PARSER); |
| + return getInts(reader, field, null); |
| } |
| |
| // inherit javadocs |
| public int[] getInts(IndexReader reader, String field, IntParser parser) |
| throws IOException { |
| - return (int[]) intsCache.get(reader, new Entry(field, parser)); |
| + return (int[]) reader.getCachedData |
| + (new IntArrayCacheKey(field, parser)).getPayload(); |
| } |
| |
| - Cache intsCache = new Cache() { |
| |
| - protected Object createValue(IndexReader reader, Object entryKey) |
| - throws IOException { |
| - Entry entry = (Entry) entryKey; |
| - String field = entry.field; |
| - IntParser parser = (IntParser) entry.custom; |
| - final int[] retArray = new int[reader.maxDoc()]; |
| - TermDocs termDocs = reader.termDocs(); |
| - TermEnum termEnum = reader.terms (new Term (field, "")); |
| - try { |
| - do { |
| - Term term = termEnum.term(); |
| - if (term==null || term.field() != field) break; |
| - int termval = parser.parseInt(term.text()); |
| - termDocs.seek (termEnum); |
| - while (termDocs.next()) { |
| - retArray[termDocs.doc()] = termval; |
| - } |
| - } while (termEnum.next()); |
| - } finally { |
| - termDocs.close(); |
| - termEnum.close(); |
| - } |
| - return retArray; |
| - } |
| - }; |
| |
| - |
| // inherit javadocs |
| public float[] getFloats (IndexReader reader, String field) |
| throws IOException { |
| - return getFloats(reader, field, FLOAT_PARSER); |
| + return getFloats(reader, field, null); |
| } |
| |
| // inherit javadocs |
| public float[] getFloats(IndexReader reader, String field, FloatParser parser) |
| throws IOException { |
| - return (float[]) floatsCache.get(reader, new Entry(field, parser)); |
| + return (float[]) reader.getCachedData |
| + (new FloatArrayCacheKey(field, parser)).getPayload(); |
| } |
| |
| - Cache floatsCache = new Cache() { |
| - |
| - protected Object createValue(IndexReader reader, Object entryKey) |
| - throws IOException { |
| - Entry entry = (Entry) entryKey; |
| - String field = entry.field; |
| - FloatParser parser = (FloatParser) entry.custom; |
| - final float[] retArray = new float[reader.maxDoc()]; |
| - TermDocs termDocs = reader.termDocs(); |
| - TermEnum termEnum = reader.terms (new Term (field, "")); |
| - try { |
| - do { |
| - Term term = termEnum.term(); |
| - if (term==null || term.field() != field) break; |
| - float termval = parser.parseFloat(term.text()); |
| - termDocs.seek (termEnum); |
| - while (termDocs.next()) { |
| - retArray[termDocs.doc()] = termval; |
| - } |
| - } while (termEnum.next()); |
| - } finally { |
| - termDocs.close(); |
| - termEnum.close(); |
| - } |
| - return retArray; |
| - } |
| - }; |
| - |
| // inherit javadocs |
| public String[] getStrings(IndexReader reader, String field) |
| throws IOException { |
| - return (String[]) stringsCache.get(reader, field); |
| + return (String[]) reader.getCachedData |
| + (new StringArrayCacheKey(field)).getPayload(); |
| } |
| |
| - Cache stringsCache = new Cache() { |
| - |
| - protected Object createValue(IndexReader reader, Object fieldKey) |
| - throws IOException { |
| - String field = ((String) fieldKey).intern(); |
| - final String[] retArray = new String[reader.maxDoc()]; |
| - TermDocs termDocs = reader.termDocs(); |
| - TermEnum termEnum = reader.terms (new Term (field, "")); |
| - try { |
| - do { |
| - Term term = termEnum.term(); |
| - if (term==null || term.field() != field) break; |
| - String termval = term.text(); |
| - termDocs.seek (termEnum); |
| - while (termDocs.next()) { |
| - retArray[termDocs.doc()] = termval; |
| - } |
| - } while (termEnum.next()); |
| - } finally { |
| - termDocs.close(); |
| - termEnum.close(); |
| - } |
| - return retArray; |
| - } |
| - }; |
| - |
| // inherit javadocs |
| public StringIndex getStringIndex(IndexReader reader, String field) |
| throws IOException { |
| - return (StringIndex) stringsIndexCache.get(reader, field); |
| + StringIndexCacheKey.StringIndex data = (StringIndexCacheKey.StringIndex) |
| + reader.getCachedData(new StringIndexCacheKey(field)).getPayload(); |
| + return new StringIndex(data.order, data.lookup); |
| } |
| |
| - Cache stringsIndexCache = new Cache() { |
| - |
| - protected Object createValue(IndexReader reader, Object fieldKey) |
| - throws IOException { |
| - String field = ((String) fieldKey).intern(); |
| - final int[] retArray = new int[reader.maxDoc()]; |
| - String[] mterms = new String[reader.maxDoc()+1]; |
| - TermDocs termDocs = reader.termDocs(); |
| - TermEnum termEnum = reader.terms (new Term (field, "")); |
| - int t = 0; // current term number |
| - |
| - // an entry for documents that have no terms in this field |
| - // should a document with no terms be at top or bottom? |
| - // this puts them at the top - if it is changed, FieldDocSortedHitQueue |
| - // needs to change as well. |
| - mterms[t++] = null; |
| - |
| - try { |
| - do { |
| - Term term = termEnum.term(); |
| - if (term==null || term.field() != field) break; |
| - |
| - // store term text |
| - // we expect that there is at most one term per document |
| - if (t >= mterms.length) throw new RuntimeException ("there are more terms than " + |
| - "documents in field \"" + field + "\", but it's impossible to sort on " + |
| - "tokenized fields"); |
| - mterms[t] = term.text(); |
| - |
| - termDocs.seek (termEnum); |
| - while (termDocs.next()) { |
| - retArray[termDocs.doc()] = t; |
| - } |
| - |
| - t++; |
| - } while (termEnum.next()); |
| - } finally { |
| - termDocs.close(); |
| - termEnum.close(); |
| - } |
| - |
| - if (t == 0) { |
| - // if there are no terms, make the term array |
| - // have a single null entry |
| - mterms = new String[1]; |
| - } else if (t < mterms.length) { |
| - // if there are less terms than documents, |
| - // trim off the dead array space |
| - String[] terms = new String[t]; |
| - System.arraycopy (mterms, 0, terms, 0, t); |
| - mterms = terms; |
| - } |
| - |
| - StringIndex value = new StringIndex (retArray, mterms); |
| - return value; |
| - } |
| - }; |
| - |
| - /** The pattern used to detect integer values in a field */ |
| - /** removed for java 1.3 compatibility |
| - protected static final Pattern pIntegers = Pattern.compile ("[0-9\\-]+"); |
| - **/ |
| - |
| - /** The pattern used to detect float values in a field */ |
| - /** |
| - * removed for java 1.3 compatibility |
| - * protected static final Object pFloats = Pattern.compile ("[0-9+\\-\\.eEfFdD]+"); |
| - */ |
| - |
| // inherit javadocs |
| public Object getAuto(IndexReader reader, String field) throws IOException { |
| - return autoCache.get(reader, field); |
| - } |
| |
| - Cache autoCache = new Cache() { |
| + field = ((String)field).intern(); |
| + TermEnum enumerator = reader.terms (new Term (field, "")); |
| + try { |
| + Term term = enumerator.term(); |
| + if (term == null) { |
| + throw new RuntimeException ("no terms in field " + field + " - cannot determine sort type"); |
| + } |
| + CacheKey ret = null; |
| + if (term.field() == field) { |
| + String termtext = term.text().trim(); |
| |
| - protected Object createValue(IndexReader reader, Object fieldKey) |
| - throws IOException { |
| - String field = ((String)fieldKey).intern(); |
| - TermEnum enumerator = reader.terms (new Term (field, "")); |
| - try { |
| - Term term = enumerator.term(); |
| - if (term == null) { |
| - throw new RuntimeException ("no terms in field " + field + " - cannot determine sort type"); |
| - } |
| - Object ret = null; |
| - if (term.field() == field) { |
| - String termtext = term.text().trim(); |
| + /** |
| + * Java 1.4 level code: |
| |
| - /** |
| - * Java 1.4 level code: |
| + if (pIntegers.matcher(termtext).matches()) |
| + return IntegerSortedHitQueue.comparator (reader, enumerator, field); |
| |
| - if (pIntegers.matcher(termtext).matches()) |
| - return IntegerSortedHitQueue.comparator (reader, enumerator, field); |
| + else if (pFloats.matcher(termtext).matches()) |
| + return FloatSortedHitQueue.comparator (reader, enumerator, field); |
| + */ |
| |
| - else if (pFloats.matcher(termtext).matches()) |
| - return FloatSortedHitQueue.comparator (reader, enumerator, field); |
| - */ |
| - |
| - // Java 1.3 level code: |
| + // Java 1.3 level code: |
| + try { |
| + Integer.parseInt (termtext); |
| + ret = new IntArrayCacheKey(field); |
| + } catch (NumberFormatException nfe1) { |
| try { |
| - Integer.parseInt (termtext); |
| - ret = getInts (reader, field); |
| - } catch (NumberFormatException nfe1) { |
| - try { |
| - Float.parseFloat (termtext); |
| - ret = getFloats (reader, field); |
| - } catch (NumberFormatException nfe3) { |
| - ret = getStringIndex (reader, field); |
| - } |
| - } |
| - } else { |
| - throw new RuntimeException ("field \"" + field + "\" does not appear to be indexed"); |
| + Float.parseFloat (termtext); |
| + ret = new FloatArrayCacheKey(field); |
| + } catch (NumberFormatException nfe3) { |
| + ret = new StringArrayCacheKey(field); |
| + } |
| } |
| - return ret; |
| - } finally { |
| - enumerator.close(); |
| + } else { |
| + throw new RuntimeException ("field \"" + field + "\" does not appear to be indexed"); |
| } |
| + return ret; |
| + } finally { |
| + enumerator.close(); |
| } |
| - }; |
| + } |
| |
| // inherit javadocs |
| public Comparable[] getCustom(IndexReader reader, String field, |
| SortComparator comparator) throws IOException { |
| - return (Comparable[]) customCache.get(reader, new Entry(field, comparator)); |
| + |
| + return (Comparable[]) |
| + reader.getCachedData(new SortComparatorCacheKey |
| + (field, comparator)).getPayload(); |
| } |
| - |
| - Cache customCache = new Cache() { |
| - |
| - protected Object createValue(IndexReader reader, Object entryKey) |
| - throws IOException { |
| - Entry entry = (Entry) entryKey; |
| - String field = entry.field; |
| - SortComparator comparator = (SortComparator) entry.custom; |
| - final Comparable[] retArray = new Comparable[reader.maxDoc()]; |
| - TermDocs termDocs = reader.termDocs(); |
| - TermEnum termEnum = reader.terms (new Term (field, "")); |
| - try { |
| - do { |
| - Term term = termEnum.term(); |
| - if (term==null || term.field() != field) break; |
| - Comparable termval = comparator.getComparable (term.text()); |
| - termDocs.seek (termEnum); |
| - while (termDocs.next()) { |
| - retArray[termDocs.doc()] = termval; |
| - } |
| - } while (termEnum.next()); |
| - } finally { |
| - termDocs.close(); |
| - termEnum.close(); |
| - } |
| - return retArray; |
| - } |
| - }; |
| |
| } |
| |
| Index: src/java/org/apache/lucene/search/FieldDocSortedHitQueue.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/FieldDocSortedHitQueue.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/FieldDocSortedHitQueue.java (working copy)
|
| @@ -134,6 +134,7 @@
|
| case SortField.STRING:{ |
| String s1 = (String) docA.fields[i]; |
| String s2 = (String) docB.fields[i]; |
| + //TODO: update javadoc |
| // null values need to be sorted first, because of how FieldCache.getStringIndex() |
| // works - in that routine, any documents without a value in the given field are |
| // put first. If both are null, the next SortField is used |
| @@ -189,6 +190,7 @@
|
| throw new RuntimeException ("invalid SortField type: "+type); |
| } |
| } |
| + |
| if (fields[i].getReverse()) { |
| c = -c; |
| } |
| Index: src/java/org/apache/lucene/search/FieldSortedHitQueue.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/FieldSortedHitQueue.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/FieldSortedHitQueue.java (working copy)
|
| @@ -18,8 +18,18 @@
|
| */ |
| |
| import org.apache.lucene.index.IndexReader; |
| +import org.apache.lucene.index.cache.ByteFieldCacheKey; |
| +import org.apache.lucene.index.cache.CacheKey; |
| +import org.apache.lucene.index.cache.DoubleFieldCacheKey; |
| +import org.apache.lucene.index.cache.FieldValues; |
| +import org.apache.lucene.index.cache.FloatFieldCacheKey; |
| +import org.apache.lucene.index.cache.IntFieldCacheKey; |
| +import org.apache.lucene.index.cache.LongFieldCacheKey; |
| +import org.apache.lucene.index.cache.ShortFieldCacheKey; |
| +import org.apache.lucene.index.cache.StringFieldCacheKey; |
| import org.apache.lucene.util.PriorityQueue; |
| |
| + |
| import java.io.IOException; |
| import java.text.Collator; |
| import java.util.Locale; |
| @@ -158,28 +168,64 @@
|
| return fields; |
| } |
| |
| + //TODO: comparators are no longer cached here, just the field data - should return caching but what to do about FieldCacheImpl.Cache? |
| static ScoreDocComparator getCachedComparator (IndexReader reader, String field, int type, Locale locale, SortComparatorSource factory) |
| throws IOException { |
| if (type == SortField.DOC) return ScoreDocComparator.INDEXORDER; |
| if (type == SortField.SCORE) return ScoreDocComparator.RELEVANCE; |
| - FieldCacheImpl.Entry entry = (factory != null) |
| - ? new FieldCacheImpl.Entry (field, factory) |
| - : new FieldCacheImpl.Entry (field, type, locale); |
| - return (ScoreDocComparator)Comparators.get(reader, entry); |
| + |
| + ScoreDocComparator comparator; |
| + switch (type) { |
| + case SortField.AUTO: |
| + comparator = comparatorAuto (reader, field); |
| + break; |
| + case SortField.INT: |
| + comparator = comparatorInt (reader, field); |
| + break; |
| + case SortField.FLOAT: |
| + comparator = comparatorFloat (reader, field); |
| + break; |
| + case SortField.LONG: |
| + comparator = comparatorLong(reader, field); |
| + break; |
| + case SortField.DOUBLE: |
| + comparator = comparatorDouble(reader, field); |
| + break; |
| + case SortField.SHORT: |
| + comparator = comparatorShort(reader, field); |
| + break; |
| + case SortField.BYTE: |
| + comparator = comparatorByte(reader, field); |
| + break; |
| + case SortField.STRING: |
| + if (locale != null) comparator = comparatorStringLocale (reader, field, locale); |
| + else comparator = comparatorString (reader, field); |
| + break; |
| + case SortField.CUSTOM: |
| + comparator = factory.newComparator (reader, field); |
| + break; |
| + default: |
| + throw new RuntimeException ("unknown field type: "+type); |
| + } |
| + return comparator; |
| } |
| |
| /** Internal cache of comparators. Similar to FieldCache, only |
| - * caches comparators instead of term values. */ |
| + * caches comparators instead of term values. |
| + * @deprecated |
| + */ |
| static final FieldCacheImpl.Cache Comparators = new FieldCacheImpl.Cache() { |
| |
| protected Object createValue(IndexReader reader, Object entryKey) |
| throws IOException { |
| + //System.out.println("creating new cache entry for reader:" + reader + " with " + entryKey.getClass().getCanonicalName()); |
| FieldCacheImpl.Entry entry = (FieldCacheImpl.Entry) entryKey; |
| String fieldname = entry.field; |
| int type = entry.type; |
| Locale locale = entry.locale; |
| SortComparatorSource factory = (SortComparatorSource) entry.custom; |
| ScoreDocComparator comparator; |
| + |
| switch (type) { |
| case SortField.AUTO: |
| comparator = comparatorAuto (reader, fieldname); |
| @@ -219,26 +265,26 @@
|
| /** |
| * Returns a comparator for sorting hits according to a field containing bytes. |
| * @param reader Index to use. |
| - * @param fieldname Fieldable containg integer values. |
| + * @param fieldname Fieldable containing integer values. |
| * @return Comparator for sorting hits. |
| * @throws IOException If an error occurs reading the index. |
| */ |
| static ScoreDocComparator comparatorByte(final IndexReader reader, final String fieldname) |
| throws IOException { |
| final String field = fieldname.intern(); |
| - final byte[] fieldOrder = FieldCache.DEFAULT.getBytes(reader, field); |
| + final FieldValues fieldOrder = (FieldValues) reader.getCachedData(new ByteFieldCacheKey(field)).getPayload();; |
| return new ScoreDocComparator() { |
| |
| public final int compare (final ScoreDoc i, final ScoreDoc j) { |
| - final int fi = fieldOrder[i.doc]; |
| - final int fj = fieldOrder[j.doc]; |
| + final int fi = ((Byte)fieldOrder.getOrd(i.doc)).byteValue(); |
| + final int fj = ((Byte)fieldOrder.getOrd(j.doc)).byteValue(); |
| if (fi < fj) return -1; |
| if (fi > fj) return 1; |
| return 0; |
| } |
| |
| public Comparable sortValue (final ScoreDoc i) { |
| - return new Byte(fieldOrder[i.doc]); |
| + return fieldOrder.getOrd(i.doc); |
| } |
| |
| public int sortType() { |
| @@ -250,26 +296,26 @@
|
| /** |
| * Returns a comparator for sorting hits according to a field containing shorts. |
| * @param reader Index to use. |
| - * @param fieldname Fieldable containg integer values. |
| + * @param fieldname Fieldable containing integer values. |
| * @return Comparator for sorting hits. |
| * @throws IOException If an error occurs reading the index. |
| */ |
| static ScoreDocComparator comparatorShort(final IndexReader reader, final String fieldname) |
| throws IOException { |
| final String field = fieldname.intern(); |
| - final short[] fieldOrder = FieldCache.DEFAULT.getShorts(reader, field); |
| + final FieldValues fieldOrder = (FieldValues) reader.getCachedData(new ShortFieldCacheKey(field)).getPayload(); |
| return new ScoreDocComparator() { |
| |
| public final int compare (final ScoreDoc i, final ScoreDoc j) { |
| - final int fi = fieldOrder[i.doc]; |
| - final int fj = fieldOrder[j.doc]; |
| + final int fi = ((Short)fieldOrder.getOrd(i.doc)).shortValue(); |
| + final int fj = ((Short)fieldOrder.getOrd(j.doc)).shortValue(); |
| if (fi < fj) return -1; |
| if (fi > fj) return 1; |
| return 0; |
| } |
| |
| public Comparable sortValue (final ScoreDoc i) { |
| - return new Short(fieldOrder[i.doc]); |
| + return fieldOrder.getOrd(i.doc); |
| } |
| |
| public int sortType() { |
| @@ -281,26 +327,26 @@
|
| /** |
| * Returns a comparator for sorting hits according to a field containing integers. |
| * @param reader Index to use. |
| - * @param fieldname Fieldable containg integer values. |
| + * @param fieldname Fieldable containing integer values. |
| * @return Comparator for sorting hits. |
| * @throws IOException If an error occurs reading the index. |
| */ |
| static ScoreDocComparator comparatorInt (final IndexReader reader, final String fieldname) |
| throws IOException { |
| final String field = fieldname.intern(); |
| - final int[] fieldOrder = FieldCache.DEFAULT.getInts (reader, field); |
| + final FieldValues fieldOrder = (FieldValues) reader.getCachedData(new IntFieldCacheKey(field)).getPayload(); |
| return new ScoreDocComparator() { |
| |
| public final int compare (final ScoreDoc i, final ScoreDoc j) { |
| - final int fi = fieldOrder[i.doc]; |
| - final int fj = fieldOrder[j.doc]; |
| + final int fi = ((Integer)fieldOrder.getOrd(i.doc)).intValue(); |
| + final int fj = ((Integer)fieldOrder.getOrd(j.doc)).intValue(); |
| if (fi < fj) return -1; |
| if (fi > fj) return 1; |
| return 0; |
| } |
| |
| public Comparable sortValue (final ScoreDoc i) { |
| - return new Integer (fieldOrder[i.doc]); |
| + return fieldOrder.getOrd(i.doc); |
| } |
| |
| public int sortType() { |
| @@ -312,26 +358,26 @@
|
| /** |
| * Returns a comparator for sorting hits according to a field containing integers. |
| * @param reader Index to use. |
| - * @param fieldname Fieldable containg integer values. |
| + * @param fieldname Fieldable containing integer values. |
| * @return Comparator for sorting hits. |
| * @throws IOException If an error occurs reading the index. |
| */ |
| static ScoreDocComparator comparatorLong (final IndexReader reader, final String fieldname) |
| throws IOException { |
| final String field = fieldname.intern(); |
| - final long[] fieldOrder = ExtendedFieldCache.EXT_DEFAULT.getLongs (reader, field); |
| + final FieldValues fieldOrder = (FieldValues) reader.getCachedData(new LongFieldCacheKey(field)).getPayload(); |
| return new ScoreDocComparator() { |
| |
| public final int compare (final ScoreDoc i, final ScoreDoc j) { |
| - final long li = fieldOrder[i.doc]; |
| - final long lj = fieldOrder[j.doc]; |
| + final long li = ((Long)fieldOrder.getOrd(i.doc)).longValue(); |
| + final long lj = ((Long)fieldOrder.getOrd(j.doc)).longValue(); |
| if (li < lj) return -1; |
| if (li > lj) return 1; |
| return 0; |
| } |
| |
| public Comparable sortValue (final ScoreDoc i) { |
| - return new Long(fieldOrder[i.doc]); |
| + return fieldOrder.getOrd(i.doc); |
| } |
| |
| public int sortType() { |
| @@ -344,26 +390,27 @@
|
| /** |
| * Returns a comparator for sorting hits according to a field containing floats. |
| * @param reader Index to use. |
| - * @param fieldname Fieldable containg float values. |
| + * @param fieldname Fieldable containing float values. |
| * @return Comparator for sorting hits. |
| * @throws IOException If an error occurs reading the index. |
| */ |
| static ScoreDocComparator comparatorFloat (final IndexReader reader, final String fieldname) |
| throws IOException { |
| final String field = fieldname.intern(); |
| - final float[] fieldOrder = FieldCache.DEFAULT.getFloats (reader, field); |
| + final FieldValues fieldOrder = (FieldValues) reader.getCachedData(new FloatFieldCacheKey(field)).getPayload(); |
| + |
| return new ScoreDocComparator () { |
| |
| public final int compare (final ScoreDoc i, final ScoreDoc j) { |
| - final float fi = fieldOrder[i.doc]; |
| - final float fj = fieldOrder[j.doc]; |
| + final float fi = ((Float)fieldOrder.getOrd(i.doc)).floatValue(); |
| + final float fj = ((Float)fieldOrder.getOrd(j.doc)).floatValue(); |
| if (fi < fj) return -1; |
| if (fi > fj) return 1; |
| return 0; |
| } |
| |
| public Comparable sortValue (final ScoreDoc i) { |
| - return new Float (fieldOrder[i.doc]); |
| + return fieldOrder.getOrd(i.doc); |
| } |
| |
| public int sortType() { |
| @@ -375,26 +422,26 @@
|
| /** |
| * Returns a comparator for sorting hits according to a field containing doubles. |
| * @param reader Index to use. |
| - * @param fieldname Fieldable containg float values. |
| + * @param fieldname Fieldable containing float values. |
| * @return Comparator for sorting hits. |
| * @throws IOException If an error occurs reading the index. |
| */ |
| static ScoreDocComparator comparatorDouble(final IndexReader reader, final String fieldname) |
| throws IOException { |
| final String field = fieldname.intern(); |
| - final double[] fieldOrder = ExtendedFieldCache.EXT_DEFAULT.getDoubles (reader, field); |
| + final FieldValues fieldOrder = (FieldValues) reader.getCachedData(new DoubleFieldCacheKey(field)).getPayload(); |
| return new ScoreDocComparator () { |
| |
| public final int compare (final ScoreDoc i, final ScoreDoc j) { |
| - final double di = fieldOrder[i.doc]; |
| - final double dj = fieldOrder[j.doc]; |
| + final double di = ((Double)fieldOrder.getOrd(i.doc)).doubleValue(); |
| + final double dj = ((Double)fieldOrder.getOrd(j.doc)).doubleValue(); |
| if (di < dj) return -1; |
| if (di > dj) return 1; |
| return 0; |
| } |
| |
| public Comparable sortValue (final ScoreDoc i) { |
| - return new Double (fieldOrder[i.doc]); |
| + return fieldOrder.getOrd(i.doc); |
| } |
| |
| public int sortType() { |
| @@ -406,26 +453,28 @@
|
| /** |
| * Returns a comparator for sorting hits according to a field containing strings. |
| * @param reader Index to use. |
| - * @param fieldname Fieldable containg string values. |
| + * @param fieldname Fieldable containing string values. |
| * @return Comparator for sorting hits. |
| * @throws IOException If an error occurs reading the index. |
| */ |
| static ScoreDocComparator comparatorString (final IndexReader reader, final String fieldname) |
| throws IOException { |
| final String field = fieldname.intern(); |
| - final FieldCache.StringIndex index = FieldCache.DEFAULT.getStringIndex (reader, field); |
| + final FieldValues data = (FieldValues) |
| + reader.getCachedData(new StringFieldCacheKey(field)).getPayload(); |
| + |
| return new ScoreDocComparator () { |
| |
| public final int compare (final ScoreDoc i, final ScoreDoc j) { |
| - final int fi = index.order[i.doc]; |
| - final int fj = index.order[j.doc]; |
| + final int fi = ((Integer)data.getOrd(i.doc)).intValue(); |
| + final int fj = ((Integer)data.getOrd(j.doc)).intValue(); |
| if (fi < fj) return -1; |
| if (fi > fj) return 1; |
| return 0; |
| } |
| |
| public Comparable sortValue (final ScoreDoc i) { |
| - return index.lookup[index.order[i.doc]]; |
| + return (String)data.getValue(i.doc); |
| } |
| |
| public int sortType() { |
| @@ -437,7 +486,7 @@
|
| /** |
| * Returns a comparator for sorting hits according to a field containing strings. |
| * @param reader Index to use. |
| - * @param fieldname Fieldable containg string values. |
| + * @param fieldname Fieldable containing string values. |
| * @return Comparator for sorting hits. |
| * @throws IOException If an error occurs reading the index. |
| */ |
| @@ -445,25 +494,26 @@
|
| throws IOException { |
| final Collator collator = Collator.getInstance (locale); |
| final String field = fieldname.intern(); |
| - final String[] index = FieldCache.DEFAULT.getStrings (reader, field); |
| + |
| + final FieldValues data = (FieldValues) reader.getCachedData(new StringFieldCacheKey(field)).getPayload(); |
| return new ScoreDocComparator() { |
| |
| public final int compare(final ScoreDoc i, final ScoreDoc j) { |
| - String is = index[i.doc]; |
| - String js = index[j.doc]; |
| - if (is == js) { |
| - return 0; |
| - } else if (is == null) { |
| - return -1; |
| - } else if (js == null) { |
| - return 1; |
| - } else { |
| - return collator.compare(is, js); |
| - } |
| - } |
| + String is = ((String)data.getValue(i.doc)); |
| + String js = ((String)data.getValue(j.doc)); |
| + if (is == js) { |
| + return 0; |
| + } else if (is == null) { |
| + return -1; |
| + } else if (js == null) { |
| + return 1; |
| + } else { |
| + return collator.compare(is, js); |
| + } |
| + } |
| |
| public Comparable sortValue (final ScoreDoc i) { |
| - return index[i.doc]; |
| + return data.getValue(i.doc); |
| } |
| |
| public int sortType() { |
| @@ -478,24 +528,23 @@
|
| * floats or strings. Once the type is determined, one of the other static methods |
| * in this class is called to get the comparator. |
| * @param reader Index to use. |
| - * @param fieldname Fieldable containg values. |
| + * @param fieldname Fieldable containing values. |
| * @return Comparator for sorting hits. |
| * @throws IOException If an error occurs reading the index. |
| */ |
| static ScoreDocComparator comparatorAuto (final IndexReader reader, final String fieldname) |
| throws IOException { |
| final String field = fieldname.intern(); |
| - Object lookupArray = ExtendedFieldCache.EXT_DEFAULT.getAuto (reader, field); |
| - if (lookupArray instanceof FieldCache.StringIndex) { |
| + Object lookupArray = CacheKey.getAutoCacheKey(reader, field); |
| + //System.out.println(lookupArray.getClass().getCanonicalName()); |
| + if (lookupArray instanceof StringFieldCacheKey) { |
| return comparatorString (reader, field); |
| - } else if (lookupArray instanceof int[]) { |
| + } else if (lookupArray instanceof IntFieldCacheKey) { |
| return comparatorInt (reader, field); |
| - } else if (lookupArray instanceof long[]) { |
| + } else if (lookupArray instanceof LongFieldCacheKey) { |
| return comparatorLong (reader, field); |
| - } else if (lookupArray instanceof float[]) { |
| + } else if (lookupArray instanceof FloatFieldCacheKey) { |
| return comparatorFloat (reader, field); |
| - } else if (lookupArray instanceof String[]) { |
| - return comparatorString (reader, field); |
| } else { |
| throw new RuntimeException ("unknown data type in field '"+field+"'"); |
| } |
| Index: src/java/org/apache/lucene/search/function/ByteFieldSource.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/function/ByteFieldSource.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/function/ByteFieldSource.java (working copy)
|
| @@ -36,6 +36,7 @@
|
| * |
| * @see org.apache.lucene.search.function.FieldCacheSource for requirements |
| * on the field. |
| + * TODO: deprecated methods/classes used |
| */ |
| public class ByteFieldSource extends FieldCacheSource { |
| private FieldCache.ByteParser parser; |
| Index: src/java/org/apache/lucene/search/function/FloatFieldSource.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/function/FloatFieldSource.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/function/FloatFieldSource.java (working copy)
|
| @@ -38,6 +38,8 @@
|
| * on the field. |
| * |
| * @author yonik |
| + * |
| + * TODO: deprecated methods/classes used |
| */ |
| public class FloatFieldSource extends FieldCacheSource { |
| private FieldCache.FloatParser parser; |
| Index: src/java/org/apache/lucene/search/function/IntFieldSource.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/function/IntFieldSource.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/function/IntFieldSource.java (working copy)
|
| @@ -37,7 +37,7 @@
|
| * @see org.apache.lucene.search.function.FieldCacheSource for requirements |
| * on the field. |
| * |
| - * |
| + * TODO: deprecated methods/classes used |
| */ |
| public class IntFieldSource extends FieldCacheSource { |
| private FieldCache.IntParser parser; |
| Index: src/java/org/apache/lucene/search/function/OrdFieldSource.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/function/OrdFieldSource.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/function/OrdFieldSource.java (working copy)
|
| @@ -45,6 +45,8 @@
|
| * supported anymore in such a case.</font> |
| * |
| * @author yonik |
| + * |
| + * TODO: deprecated methods/classes used |
| */ |
| |
| public class OrdFieldSource extends ValueSource { |
| Index: src/java/org/apache/lucene/search/function/ReverseOrdFieldSource.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/function/ReverseOrdFieldSource.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/function/ReverseOrdFieldSource.java (working copy)
|
| @@ -46,6 +46,7 @@
|
| * supported anymore in such a case.</font> |
| * |
| * @author yonik |
| + * TODO: deprecated methods/classes used |
| */ |
| |
| public class ReverseOrdFieldSource extends ValueSource { |
| Index: src/java/org/apache/lucene/search/function/ShortFieldSource.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/function/ShortFieldSource.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/function/ShortFieldSource.java (working copy)
|
| @@ -36,6 +36,7 @@
|
| * |
| * @see org.apache.lucene.search.function.FieldCacheSource for requirements |
| * on the field. |
| + * TODO: deprecated methods/classes used |
| */ |
| public class ShortFieldSource extends FieldCacheSource { |
| private FieldCache.ShortParser parser; |
| Index: src/java/org/apache/lucene/search/SortComparator.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/SortComparator.java (revision 642339)
|
| +++ src/java/org/apache/lucene/search/SortComparator.java (working copy)
|
| @@ -46,7 +46,9 @@
|
| public ScoreDocComparator newComparator (final IndexReader reader, final String fieldname) |
| throws IOException { |
| final String field = fieldname.intern(); |
| - final Comparable[] cachedValues = FieldCache.DEFAULT.getCustom (reader, field, SortComparator.this); |
| + final Comparable[] cachedValues = (Comparable[]) |
| + reader.getCachedData(new SortComparatorCacheKey |
| + (field, SortComparator.this)).getPayload(); |
| |
| return new ScoreDocComparator() { |
| |
| Index: src/java/org/apache/lucene/search/SortComparatorCacheKey.java
|
| ===================================================================
|
| --- src/java/org/apache/lucene/search/SortComparatorCacheKey.java (revision 0)
|
| +++ src/java/org/apache/lucene/search/SortComparatorCacheKey.java (revision 0)
|
| @@ -0,0 +1,91 @@
|
| +package org.apache.lucene.search;
|
| +
|
| +/**
|
| + * 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.
|
| + */
|
| +
|
| +import org.apache.lucene.index.cache.*;
|
| +import org.apache.lucene.index.IndexReader;
|
| +import org.apache.lucene.index.Term;
|
| +import org.apache.lucene.index.TermDocs;
|
| +import org.apache.lucene.index.TermEnum;
|
| +
|
| +import org.apache.lucene.search.SortComparator;
|
| +
|
| +import java.io.IOException;
|
| +
|
| +/* :TODO: javadocs
|
| + * :TODO: setup with FieldValues for faster reopen
|
| + * :TODO: this class must live in o.a.l.search because of access level of comparator.getComparable
|
| + */
|
| +public class SortComparatorCacheKey extends CacheKey {
|
| +
|
| + String field;
|
| + SortComparator comparator;
|
| +
|
| + public SortComparatorCacheKey(String f, SortComparator c) {
|
| + field = f.intern();
|
| + comparator = c;
|
| + }
|
| +
|
| + public int hashCode() {
|
| + final int prime = 31;
|
| + int result = prime + ((comparator == null) ? 0 : comparator.hashCode());
|
| + result = prime * result + ((field == null) ? 0 : field.hashCode());
|
| + return result;
|
| + }
|
| +
|
| + public boolean equals(Object obj) {
|
| + if (this == obj)
|
| + return true;
|
| + if (getClass() != obj.getClass())
|
| + return false;
|
| + final SortComparatorCacheKey other = (SortComparatorCacheKey) obj;
|
| + if (comparator == null) {
|
| + if (other.comparator != null)
|
| + return false;
|
| + } else if (!comparator.equals(other.comparator))
|
| + return false;
|
| + if (field == null) {
|
| + if (other.field != null)
|
| + return false;
|
| + } else if (!field.equals(other.field))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + public CacheData buildData(IndexReader reader) throws IOException {
|
| +
|
| + final Comparable[] retArray = new Comparable[reader.maxDoc()];
|
| + TermDocs termDocs = reader.termDocs();
|
| + TermEnum termEnum = reader.terms (new Term (field, ""));
|
| + try {
|
| + do {
|
| + Term term = termEnum.term();
|
| + if (term==null || term.field() != field) break;
|
| + Comparable termval = comparator.getComparable (term.text());
|
| + termDocs.seek (termEnum);
|
| + while (termDocs.next()) {
|
| + retArray[termDocs.doc()] = termval;
|
| + }
|
| + } while (termEnum.next());
|
| + } finally {
|
| + termDocs.close();
|
| + termEnum.close();
|
| + }
|
| + return new CacheData(retArray);
|
| + }
|
| +}
|