From 999f7ab30d566dae4880a851183a98c7e26a003f Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Thu, 21 Aug 2014 22:15:01 +0000 Subject: [PATCH] close DV producers on exception git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1619609 13f79535-47bb-0310-9956-ffa450edef68 --- .../index/SegmentDocValuesProducer.java | 110 ++++++++++-------- 1 file changed, 63 insertions(+), 47 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentDocValuesProducer.java b/lucene/core/src/java/org/apache/lucene/index/SegmentDocValuesProducer.java index 933b103f4a6..dc99a0402ed 100644 --- a/lucene/core/src/java/org/apache/lucene/index/SegmentDocValuesProducer.java +++ b/lucene/core/src/java/org/apache/lucene/index/SegmentDocValuesProducer.java @@ -48,58 +48,74 @@ class SegmentDocValuesProducer extends DocValuesProducer { final List dvGens = new ArrayList<>(); SegmentDocValuesProducer(SegmentCommitInfo si, Directory dir, FieldInfos fieldInfos, SegmentDocValues segDocValues, DocValuesFormat dvFormat) throws IOException { - Version ver = si.info.getVersion(); - if (ver != null && ver.onOrAfter(Version.LUCENE_4_9_0)) { - DocValuesProducer baseProducer = null; - for (FieldInfo fi : fieldInfos) { - if (!fi.hasDocValues()) continue; - long docValuesGen = fi.getDocValuesGen(); - if (docValuesGen == -1) { - if (baseProducer == null) { - // the base producer gets all the fields, so the Codec can validate properly - baseProducer = segDocValues.getDocValuesProducer(docValuesGen, si, IOContext.READ, dir, dvFormat, fieldInfos); - dvGens.add(docValuesGen); - dvProducers.add(baseProducer); + boolean success = false; + try { + Version ver = si.info.getVersion(); + if (ver != null && ver.onOrAfter(Version.LUCENE_4_9_0)) { + DocValuesProducer baseProducer = null; + for (FieldInfo fi : fieldInfos) { + if (!fi.hasDocValues()) { + continue; + } + long docValuesGen = fi.getDocValuesGen(); + if (docValuesGen == -1) { + if (baseProducer == null) { + // the base producer gets all the fields, so the Codec can validate properly + baseProducer = segDocValues.getDocValuesProducer(docValuesGen, si, IOContext.READ, dir, dvFormat, fieldInfos); + dvGens.add(docValuesGen); + dvProducers.add(baseProducer); + } + dvProducersByField.put(fi.name, baseProducer); + } else { + assert !dvGens.contains(docValuesGen); + final DocValuesProducer dvp = segDocValues.getDocValuesProducer(docValuesGen, si, IOContext.READ, dir, dvFormat, new FieldInfos(new FieldInfo[] { fi })); + dvGens.add(docValuesGen); + dvProducers.add(dvp); + dvProducersByField.put(fi.name, dvp); + } + } + } else { + // For pre-4.9 indexes, especially with doc-values updates, multiple + // FieldInfos could belong to the same dvGen. Therefore need to make sure + // we initialize each DocValuesProducer once per gen. + Map> genInfos = new HashMap<>(); + for (FieldInfo fi : fieldInfos) { + if (!fi.hasDocValues()) { + continue; + } + List genFieldInfos = genInfos.get(fi.getDocValuesGen()); + if (genFieldInfos == null) { + genFieldInfos = new ArrayList<>(); + genInfos.put(fi.getDocValuesGen(), genFieldInfos); + } + genFieldInfos.add(fi); + } + + for (Map.Entry> e : genInfos.entrySet()) { + long docValuesGen = e.getKey(); + List infos = e.getValue(); + final DocValuesProducer dvp; + if (docValuesGen == -1) { + // we need to send all FieldInfos to gen=-1, but later we need to + // record the DVP only for the "true" gen=-1 fields (not updated) + dvp = segDocValues.getDocValuesProducer(docValuesGen, si, IOContext.READ, dir, dvFormat, fieldInfos); + } else { + dvp = segDocValues.getDocValuesProducer(docValuesGen, si, IOContext.READ, dir, dvFormat, new FieldInfos(infos.toArray(new FieldInfo[infos.size()]))); } - dvProducersByField.put(fi.name, baseProducer); - } else { - assert !dvGens.contains(docValuesGen); - final DocValuesProducer dvp = segDocValues.getDocValuesProducer(docValuesGen, si, IOContext.READ, dir, dvFormat, new FieldInfos(new FieldInfo[] { fi })); dvGens.add(docValuesGen); dvProducers.add(dvp); - dvProducersByField.put(fi.name, dvp); + for (FieldInfo fi : infos) { + dvProducersByField.put(fi.name, dvp); + } } } - } else { - // For pre-4.9 indexes, especially with doc-values updates, multiple - // FieldInfos could belong to the same dvGen. Therefore need to make sure - // we initialize each DocValuesProducer once per gen. - Map> genInfos = new HashMap<>(); - for (FieldInfo fi : fieldInfos) { - if (!fi.hasDocValues()) continue; - List genFieldInfos = genInfos.get(fi.getDocValuesGen()); - if (genFieldInfos == null) { - genFieldInfos = new ArrayList<>(); - genInfos.put(fi.getDocValuesGen(), genFieldInfos); - } - genFieldInfos.add(fi); - } - - for (Map.Entry> e : genInfos.entrySet()) { - long docValuesGen = e.getKey(); - List infos = e.getValue(); - final DocValuesProducer dvp; - if (docValuesGen == -1) { - // we need to send all FieldInfos to gen=-1, but later we need to - // record the DVP only for the "true" gen=-1 fields (not updated) - dvp = segDocValues.getDocValuesProducer(docValuesGen, si, IOContext.READ, dir, dvFormat, fieldInfos); - } else { - dvp = segDocValues.getDocValuesProducer(docValuesGen, si, IOContext.READ, dir, dvFormat, new FieldInfos(infos.toArray(new FieldInfo[infos.size()]))); - } - dvGens.add(docValuesGen); - dvProducers.add(dvp); - for (FieldInfo fi : infos) { - dvProducersByField.put(fi.name, dvp); + success = true; + } finally { + if (success == false) { + try { + segDocValues.decRef(dvGens); + } catch (Throwable t) { + // Ignore so we keep throwing first exception } } }