This is an automated email from the ASF dual-hosted git repository. rnewson pushed a commit to branch nouveau-update-bundle in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit cf9a5b68d30231b5950697e0a18357e02c2f337b Author: Robert Newson <[email protected]> AuthorDate: Tue Mar 24 22:40:15 2026 +0000 initialise index purge seq from db purge seq --- .../java/org/apache/couchdb/nouveau/api/IndexDefinition.java | 12 ++++++++++-- .../java/org/apache/couchdb/nouveau/core/IndexManager.java | 8 ++++---- .../org/apache/couchdb/nouveau/health/IndexHealthCheck.java | 6 +++++- .../couchdb/nouveau/lucene/LuceneAnalyzerFactoryTest.java | 9 +++++++-- src/nouveau/src/nouveau_index_updater.erl | 12 +++++++----- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/api/IndexDefinition.java b/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/api/IndexDefinition.java index 5b800a3ea..c78f1ade8 100644 --- a/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/api/IndexDefinition.java +++ b/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/api/IndexDefinition.java @@ -19,21 +19,24 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import java.util.Map; import java.util.Optional; import java.util.OptionalInt; +import java.util.OptionalLong; @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) public record IndexDefinition( @Min(LEGACY_LUCENE_VERSION) @Max(LATEST_LUCENE_VERSION) OptionalInt luceneVersion, @NotEmpty String defaultAnalyzer, - Optional<Map<@NotEmpty String, @NotEmpty String>> fieldAnalyzers) { + Optional<Map<@NotEmpty String, @NotEmpty String>> fieldAnalyzers, + @NotNull OptionalLong initialPurgeSeq) { public static final int LEGACY_LUCENE_VERSION = 9; public static final int LATEST_LUCENE_VERSION = 10; public IndexDefinition() { - this(OptionalInt.of(LATEST_LUCENE_VERSION), "standard", Optional.empty()); + this(OptionalInt.of(LATEST_LUCENE_VERSION), "standard", Optional.empty(), OptionalLong.empty()); } @JsonIgnore @@ -45,4 +48,9 @@ public record IndexDefinition( public boolean isLatestVersion() { return luceneVersion.getAsInt() == LATEST_LUCENE_VERSION; } + + @JsonIgnore + public long initialPurgeSeqAsLong() { + return initialPurgeSeq.orElse(0L); + } } diff --git a/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/core/IndexManager.java b/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/core/IndexManager.java index 6120f8703..62c8ee803 100644 --- a/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/core/IndexManager.java +++ b/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/core/IndexManager.java @@ -401,16 +401,16 @@ public final class IndexManager implements Managed { } config.setUseCompoundFile(false); final IndexWriter writer = new IndexWriter(dir, config); - final long updateSeq = getSeq(writer, "update_seq"); - final long purgeSeq = getSeq(writer, "purge_seq"); + final long updateSeq = getSeq(writer, "update_seq", 0); + final long purgeSeq = getSeq(writer, "purge_seq", indexDefinition.initialPurgeSeqAsLong()); final SearcherManager searcherManager = new SearcherManager(writer, searcherFactory); return new LuceneIndex(analyzer, writer, updateSeq, purgeSeq, searcherManager); } - private long getSeq(final IndexWriter writer, final String key) throws IOException { + private long getSeq(final IndexWriter writer, final String key, final long defaultValue) throws IOException { final Iterable<Map.Entry<String, String>> commitData = writer.getLiveCommitData(); if (commitData == null) { - return 0L; + return defaultValue; } for (Map.Entry<String, String> entry : commitData) { if (entry.getKey().equals(key)) { diff --git a/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/health/IndexHealthCheck.java b/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/health/IndexHealthCheck.java index 5b4e7beb8..be9fa50f6 100644 --- a/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/health/IndexHealthCheck.java +++ b/extra/nouveau/src/main/java/org/apache/couchdb/nouveau/health/IndexHealthCheck.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.OptionalInt; +import java.util.OptionalLong; import org.apache.couchdb.nouveau.api.BulkUpdateRequest; import org.apache.couchdb.nouveau.api.DocumentUpdate; import org.apache.couchdb.nouveau.api.DocumentUpdateRequest; @@ -47,7 +48,10 @@ public final class IndexHealthCheck extends HealthCheck { indexResource.createIndex( name, new IndexDefinition( - OptionalInt.of(IndexDefinition.LATEST_LUCENE_VERSION), "standard", Optional.empty())); + OptionalInt.of(IndexDefinition.LATEST_LUCENE_VERSION), + "standard", + Optional.empty(), + OptionalLong.empty())); try { indexResource.update( name, diff --git a/extra/nouveau/src/test/java/org/apache/couchdb/nouveau/lucene/LuceneAnalyzerFactoryTest.java b/extra/nouveau/src/test/java/org/apache/couchdb/nouveau/lucene/LuceneAnalyzerFactoryTest.java index ec10f156f..021af7498 100644 --- a/extra/nouveau/src/test/java/org/apache/couchdb/nouveau/lucene/LuceneAnalyzerFactoryTest.java +++ b/extra/nouveau/src/test/java/org/apache/couchdb/nouveau/lucene/LuceneAnalyzerFactoryTest.java @@ -21,6 +21,7 @@ import java.lang.reflect.Method; import java.util.Map; import java.util.Optional; import java.util.OptionalInt; +import java.util.OptionalLong; import org.apache.couchdb.nouveau.api.IndexDefinition; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.ar.ArabicAnalyzer; @@ -261,7 +262,8 @@ public class LuceneAnalyzerFactoryTest { final IndexDefinition indexDefinition = new IndexDefinition( OptionalInt.of(IndexDefinition.LATEST_LUCENE_VERSION), "standard", - Optional.of(Map.of("english", "english", "thai", "thai", "email", "email"))); + Optional.of(Map.of("english", "english", "thai", "thai", "email", "email")), + OptionalLong.empty()); final Analyzer analyzer = LuceneAnalyzerFactory.fromDefinition(indexDefinition); assertThat(analyzer).isInstanceOf(PerFieldAnalyzerWrapper.class); final Method m = PerFieldAnalyzerWrapper.class.getDeclaredMethod("getWrappedAnalyzer", String.class); @@ -280,7 +282,10 @@ public class LuceneAnalyzerFactoryTest { private void assertAnalyzer(final String name, final Class<? extends Analyzer> clazz) throws Exception { assertThat(LuceneAnalyzerFactory.newAnalyzer(name)).isInstanceOf(clazz); assertThat(LuceneAnalyzerFactory.fromDefinition(new IndexDefinition( - OptionalInt.of(IndexDefinition.LATEST_LUCENE_VERSION), name, Optional.empty()))) + OptionalInt.of(IndexDefinition.LATEST_LUCENE_VERSION), + name, + Optional.empty(), + OptionalLong.empty()))) .isInstanceOf(clazz); } } diff --git a/src/nouveau/src/nouveau_index_updater.erl b/src/nouveau/src/nouveau_index_updater.erl index 62fcb55d3..5b58d1e4c 100644 --- a/src/nouveau/src/nouveau_index_updater.erl +++ b/src/nouveau/src/nouveau_index_updater.erl @@ -50,7 +50,7 @@ update(#index{} = Index) -> {ok, Db} = couch_db:open_int(Index#index.dbname, []), try - case open_or_create_index(Index) of + case open_or_create_index(Db, Index) of {error, Reason} -> exit({error, Reason}); {ok, #{} = Info} -> @@ -200,12 +200,13 @@ flush_batch(#purge_acc{} = Acc) -> {error, Reason} end. -open_or_create_index(#index{} = Index) -> +open_or_create_index(Db, #index{} = Index) -> case nouveau_api:index_info(Index) of {ok, #{} = Info} -> {ok, Info}; {error, {not_found, _}} -> - case nouveau_api:create_index(Index, index_definition(Index)) of + InitialPurgeSeq = couch_db:get_purge_seq(Db), + case nouveau_api:create_index(Index, index_definition(Index, InitialPurgeSeq)) of ok -> nouveau_api:index_info(Index); {error, Reason} -> @@ -225,11 +226,12 @@ get_db_info(#index{} = Index) -> couch_db:close(Db) end. -index_definition(#index{} = Index) -> +index_definition(#index{} = Index, InitialPurgeSeq) -> #{ <<"lucene_version">> => Index#index.lucene_version, <<"default_analyzer">> => Index#index.default_analyzer, - <<"field_analyzers">> => Index#index.field_analyzers + <<"field_analyzers">> => Index#index.field_analyzers, + <<"initial_purge_seq">> => InitialPurgeSeq }. purge_index(Db, Index, #purge_acc{} = PurgeAcc0) ->
