Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SegmentInfos replace doesn't update userData #948

Merged
merged 5 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 33 additions & 15 deletions src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ namespace Lucene.Net.Util
/// It is recommended to configure the culture also, since they are randomly picked from a list
/// of cultures installed on a given machine, so the culture will vary from one machine to the next.
/// </para>
///
///
/// <h4><i>.runsettings</i> File Configuration Example</h4>
///
///
/// <code>
/// &lt;RunSettings&gt;
/// &lt;TestRunParameters&gt;
Expand All @@ -120,9 +120,9 @@ namespace Lucene.Net.Util
/// See the <i>.runsettings</i> documentation at: <a href="https://docs.microsoft.com/en-us/visualstudio/test/configure-unit-tests-by-using-a-dot-runsettings-file">
/// https://docs.microsoft.com/en-us/visualstudio/test/configure-unit-tests-by-using-a-dot-runsettings-file</a>.
/// </para>
///
///
/// <h4>Attribute Configuration Example</h4>
///
///
/// <code>
/// [assembly: Lucene.Net.Util.RandomSeed("0x1ffa1d067056b0e6")]
/// [assembly: NUnit.Framework.SetCulture("sw-TZ")]
Expand All @@ -134,7 +134,7 @@ namespace Lucene.Net.Util
/// Add a file named <i>lucene.testSettings.config</i> to the executable directory or
/// any directory between the executable and the root of the drive with the following contents.
/// </para>
///
///
/// <code>
/// {
/// "tests": {
Expand All @@ -160,7 +160,7 @@ namespace Lucene.Net.Util
/// <term>sw-TZ</term>
/// </item>
/// </list>
///
///
/// </summary>
[TestFixture]
public abstract partial class LuceneTestCase //: Assert // Wait long for leaked threads to complete before failure. zk needs this. - See LUCENE-3995 for rationale.
Expand Down Expand Up @@ -510,7 +510,7 @@ public SystemPropertyData()

/// <summary>
/// TODO: javadoc? </summary>
public bool UseInfoStream { get; }
public bool UseInfoStream { get; }

/// <summary>
/// A random multiplier which you should use when writing random tests:
Expand Down Expand Up @@ -1271,6 +1271,24 @@ public static void DumpArray(string label, object[] objs, TextWriter stream)
DumpEnumerator(label, iter, stream);
}

/// <summary>
/// Creates a new <see cref="IndexWriterConfig"/> with a <see cref="SnapshotDeletionPolicy"/>.
/// </summary>
/// <param name="v">The Lucene compatibility Version</param>
/// <param name="analyzer">The analyzer to use</param>
/// <returns>Returns a new <see cref="IndexWriterConfig"/>.</returns>
/// <remarks>
/// This was backported as a result of fixing lucene#12626 from Lucene 9.9.0 in Lucene.NET.
/// The later versions of this code do not have the version parameter, but keeping it here
/// for consistency with <see cref="NewIndexWriterConfig(Lucene.Net.Util.LuceneVersion,Lucene.Net.Analysis.Analyzer)"/> below.
/// </remarks>
public static IndexWriterConfig NewSnapshotIndexWriterConfig(LuceneVersion v, Analyzer analyzer)
{
IndexWriterConfig c = NewIndexWriterConfig(v, analyzer);
c.SetIndexDeletionPolicy(new SnapshotDeletionPolicy(NoDeletionPolicy.INSTANCE));
return c;
}

/// <summary>
/// Create a new <see cref="IndexWriterConfig"/> with random defaults.
/// </summary>
Expand Down Expand Up @@ -1731,7 +1749,7 @@ public static Field NewField(Random random, string name, string value, FieldType
}

/// <summary>
/// Return a random <see cref="CultureInfo"/> from the available cultures on the system.
/// Return a random <see cref="CultureInfo"/> from the available cultures on the system.
/// <para/>
/// See <a href="https://issues.apache.org/jira/browse/LUCENE-4020">https://issues.apache.org/jira/browse/LUCENE-4020</a>.
/// </summary>
Expand All @@ -1741,7 +1759,7 @@ public static CultureInfo RandomCulture(Random random) // LUCENENET specific ren
}

/// <summary>
/// Return a random <see cref="TimeZoneInfo"/> from the available timezones on the system
/// Return a random <see cref="TimeZoneInfo"/> from the available timezones on the system
/// <para/>
/// See <a href="https://issues.apache.org/jira/browse/LUCENE-4020">https://issues.apache.org/jira/browse/LUCENE-4020</a>.
/// </summary>
Expand Down Expand Up @@ -2037,7 +2055,7 @@ public static IndexSearcher NewSearcher(IndexReader r, bool maybeWrap, bool wrap
/// <summary>
/// Gets a resource from the classpath as <see cref="Stream"/>. This method should only
/// be used, if a real file is needed. To get a stream, code should prefer
/// <see cref="J2N.AssemblyExtensions.FindAndGetManifestResourceStream(Assembly, Type, string)"/> using
/// <see cref="J2N.AssemblyExtensions.FindAndGetManifestResourceStream(Assembly, Type, string)"/> using
/// <c>this.GetType().Assembly</c> and <c>this.GetType()</c>.
/// </summary>
protected virtual Stream GetDataFile(string name)
Expand Down Expand Up @@ -2879,7 +2897,7 @@ public virtual void AssertFieldInfosEquals(string info, IndexReader leftReader,

/// <summary>
/// Returns true if the file exists (can be opened), false
/// if it cannot be opened, and (unlike .NET's
/// if it cannot be opened, and (unlike .NET's
/// <see cref="System.IO.File.Exists(string)"/>) if there's some
/// unexpected error, returns <c>false</c>.
/// </summary>
Expand Down Expand Up @@ -2921,7 +2939,7 @@ public static DirectoryInfo CreateTempDir()
/// <summary>
/// Creates an empty, temporary folder with the given name <paramref name="prefix"/> under the
/// system's <see cref="Path.GetTempPath()"/> or if supplied, the <c>tempDir</c> system property.
///
///
/// <para/>The folder will be automatically removed after the
/// test class completes successfully. The test should close any file handles that would prevent
/// the folder from being removed.
Expand All @@ -2940,7 +2958,7 @@ public static DirectoryInfo CreateTempDir(string prefix)
{
throw RuntimeException.Create("Failed to get a temporary name too many times, check your temp directory and consider manually cleaning it: " + System.IO.Path.GetTempPath());
}
// LUCENENET specific - need to use a random file name instead of a sequential one or two threads may attempt to do
// LUCENENET specific - need to use a random file name instead of a sequential one or two threads may attempt to do
// two operations on a file at the same time.
//f = new DirectoryInfo(Path.Combine(System.IO.Path.GetTempPath(), "LuceneTemp", prefix + "-" + attempt));
f = new DirectoryInfo(Path.Combine(@base, "LuceneTemp", prefix + "-" + Path.GetFileNameWithoutExtension(Path.GetRandomFileName())));
Expand Down Expand Up @@ -3157,7 +3175,7 @@ internal static void LogNativeFSFactoryDebugInfo()
/// <see cref="double"/> value, chosen from (approximately) the usual
/// normal distribution with mean <c>0.0</c> and standard deviation
/// <c>1.0</c>, is pseudorandomly generated and returned.
///
///
/// <para/>This uses the <i>polar method</i> of G. E. P. Box, M. E. Muller, and
/// G. Marsaglia, as described by Donald E. Knuth in <i>The Art of
/// Computer Programming</i>, Volume 3: <i>Seminumerical Algorithms</i>,
Expand Down Expand Up @@ -3193,4 +3211,4 @@ public void OnDispose(IndexReader reader)
}
}
}
}
}
59 changes: 58 additions & 1 deletion src/Lucene.Net.Tests/Index/TestIndexWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2556,12 +2556,26 @@ public virtual void TestCommitWithUserDataOnly()
dir.Dispose();
}

// LUCENENET-specific: backport fix and test from Lucene 9.9.0 (lucene#12626, lucene#12637)
private Dictionary<string, string> GetLiveCommitData(IndexWriter writer)
{
Dictionary<string, string> data = new Dictionary<string, string>();
// LUCENENET TODO: in a post-4.8 port, this should use LiveCommitData
paulirwin marked this conversation as resolved.
Show resolved Hide resolved
foreach (var ent in writer.CommitData)
{
data.Put(ent.Key, ent.Value);
}

return data;
}

[Test]
public virtual void TestGetCommitData()
{
Directory dir = NewDirectory();
IndexWriter writer = new IndexWriter(dir, NewIndexWriterConfig(TEST_VERSION_CURRENT, null));
writer.SetCommitData(new Dictionary<string, string>() {
writer.SetCommitData(new Dictionary<string, string>()
{
{"key", "value"}
});
Assert.AreEqual("value", writer.CommitData["key"]);
Expand All @@ -2575,6 +2589,49 @@ public virtual void TestGetCommitData()
dir.Dispose();
}

// LUCENENET-specific: backport fix and test from Lucene 9.9.0 (lucene#12626, lucene#12637)
[Test]
public void TestGetCommitDataFromOldSnapshot()
{
Directory dir = NewDirectory();
IndexWriter writer = new IndexWriter(dir, NewSnapshotIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random)));
// LUCENENET TODO: in a post-4.8 port, this should use SetLiveCommitData
paulirwin marked this conversation as resolved.
Show resolved Hide resolved
writer.SetCommitData(new Dictionary<string, string>
{
{ "key", "value" },
});
assertEquals("value", GetLiveCommitData(writer)["key"]);
writer.Commit();
// Snapshot this commit to open later
IndexCommit indexCommit =
((SnapshotDeletionPolicy)writer.Config.IndexDeletionPolicy).Snapshot();
writer.Dispose();

// Modify the commit data and commit on close so the most recent commit data is different
writer = new IndexWriter(dir, NewSnapshotIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random)));
paulirwin marked this conversation as resolved.
Show resolved Hide resolved
// LUCENENET TODO: in a post-4.8 port, this should use SetLiveCommitData
paulirwin marked this conversation as resolved.
Show resolved Hide resolved
writer.SetCommitData(new Dictionary<string, string>()
{
{ "key", "value2" },
});

assertEquals("value2", GetLiveCommitData(writer)["key"]);
writer.Dispose();

// validate that when opening writer from older snapshotted index commit, the old commit data is
// visible
writer =
new IndexWriter(
dir,
NewSnapshotIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random))
paulirwin marked this conversation as resolved.
Show resolved Hide resolved
.SetOpenMode(OpenMode.APPEND)
.SetIndexCommit(indexCommit));
assertEquals("value", GetLiveCommitData(writer)["key"]);
writer.Dispose();

dir.Dispose();
}

[Test]
public virtual void TestIterableThrowsException()
{
Expand Down
12 changes: 7 additions & 5 deletions src/Lucene.Net/Index/SegmentInfos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,8 @@ internal static string SegmentNumberToString(long segment, bool allowLegacyNames
private JCG.List<SegmentCommitInfo> segments = new JCG.List<SegmentCommitInfo>();

/// <summary>
/// If non-null, information about loading segments_N files
/// will be printed here.</summary>
/// If non-null, information about loading segments_N files
/// will be printed here.</summary>
/// <seealso cref="InfoStream"/>
private static TextWriter infoStream = null;

Expand Down Expand Up @@ -891,7 +891,7 @@ public object Clone()
/// If non-null, information about retries when loading
/// the segments file will be printed to this.
/// </summary>
public static TextWriter InfoStream
public static TextWriter InfoStream
{
set =>
// LUCENENET specific - use a SafeTextWriterWrapper to ensure that if the TextWriter
Expand Down Expand Up @@ -1452,6 +1452,8 @@ internal void Replace(SegmentInfos other)
{
RollbackSegmentInfos(other.AsList());
lastGeneration = other.lastGeneration;
// LUCENENET-specific: backport fix from Lucene 9.9.0 (lucene#12626, lucene#12637)
userData = other.userData;
}

/// <summary>
Expand Down Expand Up @@ -1611,7 +1613,7 @@ internal void Remove(int index)
}

/// <summary>
/// Return true if the provided
/// Return true if the provided
/// <see cref="SegmentCommitInfo"/> is contained.
///
/// <para/><b>WARNING</b>: O(N) cost
Expand All @@ -1632,4 +1634,4 @@ internal int IndexOf(SegmentCommitInfo si)
return segments.IndexOf(si);
}
}
}
}
Loading