Index: lucene/facet/src/java/org/apache/lucene/facet/fixed/FixedFacetsAccumulator.java =================================================================== --- lucene/facet/src/java/org/apache/lucene/facet/fixed/FixedFacetsAccumulator.java (revision 0) +++ lucene/facet/src/java/org/apache/lucene/facet/fixed/FixedFacetsAccumulator.java (working copy) @@ -0,0 +1,129 @@ +package org.apache.lucene.facet.fixed; + +/* + * 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.File; +import java.io.IOException; +import java.util.List; + +import org.apache.lucene.facet.fixed.FixedFacetFields.OneDim; +import org.apache.lucene.facet.search.FacetArrays; +import org.apache.lucene.facet.search.FacetResult; +import org.apache.lucene.facet.search.FacetsAccumulator; +import org.apache.lucene.facet.search.FacetsCollector.MatchingDocs; +import org.apache.lucene.facet.taxonomy.TaxonomyReader; +import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader; +import org.apache.lucene.index.BinaryDocValues; +import org.apache.lucene.store.FSDirectory; +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.FixedBitSet; + +public class FixedFacetsAccumulator extends FacetsAccumulator { + private final FacetArrays arrays; + private final FixedFacetFields fields; + private final int totOrds; + + public FixedFacetsAccumulator(FixedFacetFields fields) throws IOException { + super(null); + this.fields = fields; + int upto = 0; + int ordBase = 0; + for(OneDim dim : fields.dims.values()) { + dim.ordBase = ordBase; + ordBase += dim.taxoReader.getSize(); + upto++; + } + totOrds = ordBase; + arrays = new FacetArrays(totOrds); + } + + @Override + public boolean requiresDocScores() { + return false; + } + + @Override + public List accumulate(List matchingDocs) throws IOException { + OneDim[] dims = fields.dims.values().toArray(new OneDim[fields.dims.size()]); + int[] counts = arrays.getIntArray(); + + // nocommit since byte[] is always fixed length, DVF + // should be faster... hmm, unless some docs have a + // different ords space / FixedFacetsAccumulator + + BytesRef scratch = new BytesRef(fields.byteUpto); + + for (MatchingDocs md : matchingDocs) { + final BinaryDocValues dv = md.context.reader().getBinaryDocValues("$facets"); + int doc = 0; + int maxDoc = md.context.reader().maxDoc(); + FixedBitSet bits = md.bits; + + while (doc < maxDoc && (doc = bits.nextSetBit(doc)) != -1) { + dv.get(doc, scratch); + if (scratch.length > 0) { + byte[] bytes = scratch.bytes; + int upto = scratch.offset; + assert scratch.length == fields.byteUpto; + //for(int i=0;i dims = new LinkedHashMap(); + + public FixedFacetFields(File path, boolean write) { + this.path = path; + this.write = write; + System.out.println("CREATE write=" + write); + } + + public void addDim(String dim, int uniqueValueCount) throws IOException { + if (dims.containsKey(dim)) { + throw new IllegalArgumentException("dim " + dim + " already added"); + } + OneDim oneDim = new OneDim(); + oneDim.dim = dim; + oneDim.uniqueValueCount = uniqueValueCount; + oneDim.byteStart = byteUpto; + File dimPath = new File(path, "taxo." + dim); + oneDim.dir = FSDirectory.open(dimPath); + System.out.println("addDim dim=" + dim + " write=" + write); + if (write) { + oneDim.taxoWriter = new DirectoryTaxonomyWriter(oneDim.dir, OpenMode.CREATE); + System.out.println(" make taxoWriter"); + } else { + oneDim.taxoReader = new DirectoryTaxonomyReader(oneDim.dir); + } + dims.put(dim, oneDim); + if (uniqueValueCount <= 1<<8) { + oneDim.byteCount = 1; + } else if (uniqueValueCount < 1<<16) { + oneDim.byteCount = 2; + } else if (uniqueValueCount < 1<<24) { + oneDim.byteCount = 3; + } else { + oneDim.byteCount = 4; + } + byteUpto += oneDim.byteCount; + } + + public DocBuilder getDocBuilder() { + return new DocBuilder(); + } + + public class DocBuilder { + final byte[] bytes = new byte[byteUpto]; + + // nocommit this "reuse" API is dangerous now: if the + // next doc fails to add a given dim it just inherits + // from last doc + + public void add(CategoryPath cp) throws IOException { + /* + if (cp.length != 2) { + throw new IllegalArgumentException("cannot handle hierarchy yet"); + } + */ + OneDim dim = dims.get(cp.components[0]); + if (dim == null) { + throw new IllegalArgumentException("dim " + cp.components[0] + " wasn't added"); + } + int ord = dim.taxoWriter.addCategory(cp); + if (ord >= dim.uniqueValueCount) { + throw new IllegalStateException("dim " + cp.components[0] + " has more values than expected: got ord=" + ord + " but expected < " + dim.uniqueValueCount); + } + + int byteUpto = dim.byteStart; + if (dim.byteCount == 1) { + bytes[byteUpto] = (byte) ord; + } else if (dim.byteCount == 2) { + bytes[byteUpto++] = (byte) (ord>>8); + bytes[byteUpto] = (byte) ord; + } else if (dim.byteCount == 3) { + bytes[byteUpto++] = (byte) (ord>>16); + bytes[byteUpto++] = (byte) (ord>>8); + bytes[byteUpto] = (byte) ord; + } else { + assert dim.byteCount == 4; + bytes[byteUpto++] = (byte) (ord>>24); + bytes[byteUpto++] = (byte) (ord>>16); + bytes[byteUpto++] = (byte) (ord>>8); + bytes[byteUpto] = (byte) ord; + } + } + + public void finish(Document doc) { + // nocommit is it really safe to not make a deep copy + // of this.bytes...? + //System.out.println(" finish bytes.length=" + bytes.length); + doc.add(new BinaryDocValuesField("$facets", new BytesRef(bytes))); + } + } + + @Override + public void close() throws IOException { + // nocommit IOUtils.close: + for(OneDim dim : dims.values()) { + if (dim.taxoWriter != null) { + dim.taxoWriter.close(); + } else { + dim.taxoReader.close(); + } + } + } +} + Property changes on: lucene/facet/src/java/org/apache/lucene/facet/fixed/FixedFacetFields.java ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property