+++ /dev/null
-package org.apache.lucene.facet.index;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.lucene.index.PayloadProcessorProvider;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.store.Directory;
-
-import org.apache.lucene.facet.index.params.CategoryListParams;
-import org.apache.lucene.facet.index.params.FacetIndexingParams;
-import org.apache.lucene.facet.taxonomy.lucene.LuceneTaxonomyWriter.OrdinalMap;
-import org.apache.lucene.util.encoding.IntDecoder;
-import org.apache.lucene.util.encoding.IntEncoder;
-
-/**
- * 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.
- */
-
-/**
- * A {@link PayloadProcessorProvider} for updating facets ordinal references,
- * based on an ordinal map. You should use this code in conjunction with merging
- * taxonomies - after you merge taxonomies, you receive an {@link OrdinalMap}
- * which maps the 'old' payloads to the 'new' ones. You can use that map to
- * re-map the payloads which contain the facets information (ordinals) either
- * before or while merging the indexes.
- * <p>
- * For re-mapping the ordinals before you merge the indexes, do the following:
- *
- * <pre>
- * // merge the old taxonomy with the new one.
- * OrdinalMap map = LuceneTaxonomyWriter.addTaxonomies();
- * int[] ordmap = map.getMap();
- *
- * // re-map the ordinals on the old directory.
- * Directory oldDir;
- * FacetsPayloadProcessorProvider fppp = new FacetsPayloadProcessorProvider(
- * oldDir, ordmap);
- * IndexWriterConfig conf = new IndexWriterConfig(VER, ANALYZER);
- * conf.setMergePolicy(new ForceOptimizeMergePolicy());
- * IndexWriter writer = new IndexWriter(oldDir, conf);
- * writer.setPayloadProcessorProvider(fppp);
- * writer.optimize();
- * writer.close();
- *
- * // merge that directory with the new index.
- * IndexWriter newWriter; // opened on the 'new' Directory
- * newWriter.addIndexes(oldDir);
- * newWriter.commit();
- * </pre>
- *
- * For re-mapping the ordinals during index merge, do the following:
- *
- * <pre>
- * // merge the old taxonomy with the new one.
- * OrdinalMap map = LuceneTaxonomyWriter.addTaxonomies();
- * int[] ordmap = map.getMap();
- *
- * // Add the index and re-map ordinals on the go
- * IndexReader r = IndexReader.open(oldDir);
- * IndexWriterConfig conf = new IndexWriterConfig(VER, ANALYZER);
- * IndexWriter writer = new IndexWriter(newDir, conf);
- * writer.setPayloadProcessorProvider(fppp);
- * writer.addIndexes(r);
- * writer.commit();
- * </pre>
- * <p>
- * <b>NOTE:</b> while the second example looks simpler, IndexWriter may trigger
- * a long merge due to addIndexes. The first example avoids this perhaps
- * unneeded merge, as well as can be done separately (e.g. on another node)
- * before the index is merged.
- *
- * @lucene.experimental
- */
-public class FacetsPayloadProcessorProvider extends PayloadProcessorProvider {
-
- private final Directory workDir;
-
- private final DirPayloadProcessor dirProcessor;
-
- /**
- * Construct FacetsPayloadProcessorProvider with FacetIndexingParams
- *
- * @param dir the {@link Directory} containing the segments to update
- * @param ordinalMap an array mapping previous facets ordinals to new ones
- * @param indexingParams the facets indexing parameters
- */
- public FacetsPayloadProcessorProvider(Directory dir, int[] ordinalMap,
- FacetIndexingParams indexingParams) {
- workDir = dir;
- dirProcessor = new FacetsDirPayloadProcessor(indexingParams, ordinalMap);
- }
-
- @Override
- public DirPayloadProcessor getDirProcessor(Directory dir) throws IOException {
- if (workDir != dir) {
- return null;
- }
- return dirProcessor;
- }
-
- public static class FacetsDirPayloadProcessor extends DirPayloadProcessor {
-
- private final Map<Term, CategoryListParams> termMap = new HashMap<Term, CategoryListParams>(1);
-
- private final int[] ordinalMap;
-
- /**
- * Construct FacetsDirPayloadProcessor with custom FacetIndexingParams
- * @param ordinalMap an array mapping previous facets ordinals to new ones
- * @param indexingParams the facets indexing parameters
- */
- protected FacetsDirPayloadProcessor(FacetIndexingParams indexingParams, int[] ordinalMap) {
- this.ordinalMap = ordinalMap;
- for (CategoryListParams params: indexingParams.getAllCategoryListParams()) {
- termMap.put(params.getTerm(), params);
- }
- }
-
- @Override
- public PayloadProcessor getProcessor(Term term) throws IOException {
- CategoryListParams params = termMap.get(term);
- if (params == null) {
- return null;
- }
- return new FacetsPayloadProcessor(params, ordinalMap);
- }
-
- }
-
- /** A PayloadProcessor for updating facets ordinal references, based on an ordinal map */
- public static class FacetsPayloadProcessor extends PayloadProcessor {
-
- private final IntEncoder encoder;
- private final IntDecoder decoder;
- private final int[] ordinalMap;
- private final ByteArrayOutputStream os = new ByteArrayOutputStream();
-
- /**
- * @param params defines the encoding of facet ordinals as payload
- * @param ordinalMap an array mapping previous facets ordinals to new ones
- */
- protected FacetsPayloadProcessor(CategoryListParams params, int[] ordinalMap) {
- encoder = params.createEncoder();
- decoder = encoder.createMatchingDecoder();
- this.ordinalMap = ordinalMap;
- }
-
- @Override
- public int payloadLength() throws IOException {
- return os.size();
- }
-
- @Override
- public byte[] processPayload(byte[] payload, int start, int length) throws IOException {
- InputStream is = new ByteArrayInputStream(payload, start, length);
- decoder.reInit(is);
- os.reset();
- encoder.reInit(os);
- long ordinal;
- while ((ordinal = decoder.decode()) != IntDecoder.EOS) {
- int newOrdinal = ordinalMap[(int)ordinal];
- encoder.encode(newOrdinal);
- }
- encoder.close();
- return os.toByteArray();
- }
- }
-
-}