mirror of https://github.com/apache/lucene.git
LUCENE-8309: Live docs are no longer backed by mutable bits.
This commit is contained in:
parent
6d69824a6b
commit
35a815b955
|
@ -115,6 +115,10 @@ API Changes
|
||||||
* LUCENE-8303: LiveDocsFormat is now only responsible for (de)serialization of
|
* LUCENE-8303: LiveDocsFormat is now only responsible for (de)serialization of
|
||||||
live docs. (Adrien Grand)
|
live docs. (Adrien Grand)
|
||||||
|
|
||||||
|
Changes in Runtime Behavior
|
||||||
|
|
||||||
|
* LUCENE-8309: Live docs are no longer backed by a FixedBitSet. (Adrien Grand)
|
||||||
|
|
||||||
New Features
|
New Features
|
||||||
|
|
||||||
* LUCENE-8200: Allow doc-values to be updated atomically together
|
* LUCENE-8200: Allow doc-values to be updated atomically together
|
||||||
|
|
|
@ -80,7 +80,7 @@ public final class Lucene50LiveDocsFormat extends LiveDocsFormat {
|
||||||
throw new CorruptIndexException("bits.deleted=" + (fbs.length() - fbs.cardinality()) +
|
throw new CorruptIndexException("bits.deleted=" + (fbs.length() - fbs.cardinality()) +
|
||||||
" info.delcount=" + info.getDelCount(), input);
|
" info.delcount=" + info.getDelCount(), input);
|
||||||
}
|
}
|
||||||
return fbs;
|
return fbs.asReadOnlyBits();
|
||||||
} catch (Throwable exception) {
|
} catch (Throwable exception) {
|
||||||
priorE = exception;
|
priorE = exception;
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -76,7 +76,7 @@ class PendingDeletes {
|
||||||
writeableLiveDocs = new FixedBitSet(info.info.maxDoc());
|
writeableLiveDocs = new FixedBitSet(info.info.maxDoc());
|
||||||
writeableLiveDocs.set(0, info.info.maxDoc());
|
writeableLiveDocs.set(0, info.info.maxDoc());
|
||||||
}
|
}
|
||||||
liveDocs = writeableLiveDocs;
|
liveDocs = writeableLiveDocs.asReadOnlyBits();
|
||||||
}
|
}
|
||||||
return writeableLiveDocs;
|
return writeableLiveDocs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -515,6 +515,12 @@ public final class FixedBitSet extends BitSet implements Bits, Accountable {
|
||||||
* Make a copy of the given bits.
|
* Make a copy of the given bits.
|
||||||
*/
|
*/
|
||||||
public static FixedBitSet copyOf(Bits bits) {
|
public static FixedBitSet copyOf(Bits bits) {
|
||||||
|
if (bits instanceof FixedBits) {
|
||||||
|
// restore the original FixedBitSet
|
||||||
|
FixedBits fixedBits = (FixedBits) bits;
|
||||||
|
bits = new FixedBitSet(fixedBits.bits, fixedBits.length);
|
||||||
|
}
|
||||||
|
|
||||||
if (bits instanceof FixedBitSet) {
|
if (bits instanceof FixedBitSet) {
|
||||||
return ((FixedBitSet)bits).clone();
|
return ((FixedBitSet)bits).clone();
|
||||||
} else {
|
} else {
|
||||||
|
@ -529,4 +535,16 @@ public final class FixedBitSet extends BitSet implements Bits, Accountable {
|
||||||
return bitSet;
|
return bitSet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert this instance to read-only {@link Bits}.
|
||||||
|
* This is useful in the case that this {@link FixedBitSet} is returned as a
|
||||||
|
* {@link Bits} instance, to make sure that consumers may not get write access
|
||||||
|
* back by casting to a {@link FixedBitSet}.
|
||||||
|
* NOTE: Changes to this {@link FixedBitSet} will be reflected on the returned
|
||||||
|
* {@link Bits}.
|
||||||
|
*/
|
||||||
|
public Bits asReadOnlyBits() {
|
||||||
|
return new FixedBits(bits, numBits);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.lucene.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immutable twin of FixedBitSet.
|
||||||
|
*/
|
||||||
|
final class FixedBits implements Bits {
|
||||||
|
|
||||||
|
final long[] bits;
|
||||||
|
final int length;
|
||||||
|
|
||||||
|
FixedBits(long[] bits, int length) {
|
||||||
|
this.bits = bits;
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean get(int index) {
|
||||||
|
assert index >= 0 && index < length: "index=" + index + ", numBits=" + length;
|
||||||
|
int i = index >> 6; // div 64
|
||||||
|
// signed shift will keep a negative index and force an
|
||||||
|
// array-index-out-of-bounds-exception, removing the need for an explicit check.
|
||||||
|
long bitmask = 1L << index;
|
||||||
|
return (bits[i] & bitmask) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int length() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -503,11 +503,14 @@ public class TestFixedBitSet extends BaseBitSetTestCase<FixedBitSet> {
|
||||||
for (int e : bits) {
|
for (int e : bits) {
|
||||||
fixedBitSet.set(e);
|
fixedBitSet.set(e);
|
||||||
}
|
}
|
||||||
FixedBitSet mutableCopy = FixedBitSet.copyOf(fixedBitSet);
|
for (boolean readOnly : new boolean[] {false, true}) {
|
||||||
assertNotSame(mutableCopy, fixedBitSet);
|
Bits bitsToCopy = readOnly ? fixedBitSet.asReadOnlyBits() : fixedBitSet;
|
||||||
|
FixedBitSet mutableCopy = FixedBitSet.copyOf(bitsToCopy);
|
||||||
|
assertNotSame(mutableCopy, bitsToCopy);
|
||||||
assertEquals(mutableCopy, fixedBitSet);
|
assertEquals(mutableCopy, fixedBitSet);
|
||||||
|
}
|
||||||
|
|
||||||
FixedBitSet mutableCopy1 = FixedBitSet.copyOf(new Bits() {
|
final Bits bitsToCopy = new Bits() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean get(int index) {
|
public boolean get(int index) {
|
||||||
|
@ -518,11 +521,27 @@ public class TestFixedBitSet extends BaseBitSetTestCase<FixedBitSet> {
|
||||||
public int length() {
|
public int length() {
|
||||||
return fixedBitSet.length();
|
return fixedBitSet.length();
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
FixedBitSet mutableCopy = FixedBitSet.copyOf(bitsToCopy);
|
||||||
|
|
||||||
assertNotSame(mutableCopy, mutableCopy1);
|
assertNotSame(bitsToCopy, mutableCopy);
|
||||||
assertNotSame(fixedBitSet, mutableCopy1);
|
assertNotSame(fixedBitSet, mutableCopy);
|
||||||
assertEquals(mutableCopy1, mutableCopy);
|
assertEquals(mutableCopy, fixedBitSet);
|
||||||
assertEquals(mutableCopy1, fixedBitSet);
|
}
|
||||||
|
|
||||||
|
public void testAsBits() {
|
||||||
|
FixedBitSet set = new FixedBitSet(10);
|
||||||
|
set.set(3);
|
||||||
|
set.set(4);
|
||||||
|
set.set(9);
|
||||||
|
Bits bits = set.asReadOnlyBits();
|
||||||
|
assertFalse(bits instanceof FixedBitSet);
|
||||||
|
assertEquals(set.length(), bits.length());
|
||||||
|
for (int i = 0; i < set.length(); ++i) {
|
||||||
|
assertEquals(set.get(i), bits.get(i));
|
||||||
|
}
|
||||||
|
// Further changes are reflected
|
||||||
|
set.set(5);
|
||||||
|
assertTrue(bits.get(5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue