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) ->

Reply via email to