This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch auto-delete-3
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/auto-delete-3 by this push:
     new 5bf9e555a return drop_count in GET /dbname info
5bf9e555a is described below

commit 5bf9e555a26ac3570f70ae2ddf09121488733ddf
Author: Robert Newson <[email protected]>
AuthorDate: Wed May 21 10:52:58 2025 +0100

    return drop_count in GET /dbname info
---
 src/couch/src/couch_bt_engine.erl           | 13 +++++++++++++
 src/couch/src/couch_bt_engine_compactor.erl |  3 ++-
 src/couch/src/couch_bt_engine_header.erl    | 12 +++++++++---
 src/couch/src/couch_db.erl                  |  6 ++++++
 src/couch/src/couch_db_engine.erl           | 10 ++++++++++
 src/fabric/src/fabric_db_info.erl           |  2 ++
 test/elixir/test/drop_seq_test.exs          | 10 ++++++++++
 7 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/src/couch/src/couch_bt_engine.erl 
b/src/couch/src/couch_bt_engine.erl
index b831337a1..9d3c97fd7 100644
--- a/src/couch/src/couch_bt_engine.erl
+++ b/src/couch/src/couch_bt_engine.erl
@@ -45,6 +45,7 @@
     get_partition_info/2,
     get_update_seq/1,
     get_drop_seq/1,
+    get_drop_count/1,
     get_uuid/1,
 
     set_revs_limit/2,
@@ -54,6 +55,7 @@
 
     set_update_seq/2,
     set_drop_seq/3,
+    increment_drop_count/1,
 
     open_docs/2,
     open_local_docs/2,
@@ -331,6 +333,9 @@ get_update_seq(#st{header = Header}) ->
 get_drop_seq(#st{header = Header}) ->
     couch_bt_engine_header:get(Header, drop_seq).
 
+get_drop_count(#st{header = Header}) ->
+    couch_bt_engine_header:get(Header, drop_count).
+
 get_uuid(#st{header = Header}) ->
     couch_bt_engine_header:get(Header, uuid).
 
@@ -835,6 +840,14 @@ set_drop_seq(#st{header = Header} = St, 
ExpectedUuidPrefix, NewDropSeq) when
             {ok, increment_update_seq(NewSt)}
     end.
 
+increment_drop_count(#st{header = Header} = St) ->
+    CurrentDropCount = get_drop_count(St),
+    NewSt = St#st{
+        header = couch_bt_engine_header:set(Header, [{drop_count, 
CurrentDropCount + 1}]),
+        needs_commit = true
+    },
+    {ok, NewSt}.
+
 copy_security(#st{header = Header} = St, SecProps) ->
     Options = [{compression, St#st.compression}],
     {ok, Ptr, _} = couch_file:append_term(St#st.fd, SecProps, Options),
diff --git a/src/couch/src/couch_bt_engine_compactor.erl 
b/src/couch/src/couch_bt_engine_compactor.erl
index 619200bce..2f230f489 100644
--- a/src/couch/src/couch_bt_engine_compactor.erl
+++ b/src/couch/src/couch_bt_engine_compactor.erl
@@ -330,7 +330,8 @@ copy_compact(#comp_st{} = CompSt) ->
             if
                 Deleted andalso Seq =< DropSeq ->
                     %% drop this document completely
-                    {ok, {AccNewSt, AccUncopied, AccUncopiedSize, 
AccCopiedSize}};
+                    {ok, NewSt2} = 
couch_bt_engine:increment_drop_count(AccNewSt),
+                    {ok, {NewSt2, AccUncopied, AccUncopiedSize, 
AccCopiedSize}};
                 AccUncopiedSize2 >= BufferSize ->
                     NewSt2 = copy_docs(
                         St, AccNewSt, lists:reverse([DocInfo | AccUncopied]), 
Retry
diff --git a/src/couch/src/couch_bt_engine_header.erl 
b/src/couch/src/couch_bt_engine_header.erl
index 9f5285d49..0d3c55a14 100644
--- a/src/couch/src/couch_bt_engine_header.erl
+++ b/src/couch/src/couch_bt_engine_header.erl
@@ -39,7 +39,8 @@
     uuid/1,
     epochs/1,
     compacted_seq/1,
-    drop_seq/1
+    drop_seq/1,
+    drop_count/1
 ]).
 
 -include_lib("stdlib/include/assert.hrl").
@@ -73,7 +74,8 @@
     compacted_seq,
     purge_infos_limit = 1000,
     props_ptr,
-    drop_seq = 0
+    drop_seq = 0,
+    drop_count = 0
 }).
 
 -define(PARTITION_DISK_VERSION, 8).
@@ -90,7 +92,8 @@ from(Header0) ->
         uuid = Header#db_header.uuid,
         epochs = Header#db_header.epochs,
         compacted_seq = Header#db_header.compacted_seq,
-        drop_seq = Header#db_header.drop_seq
+        drop_seq = Header#db_header.drop_seq,
+        drop_count = Header#db_header.drop_count
     }.
 
 is_header(Header) ->
@@ -182,6 +185,9 @@ compacted_seq(Header) ->
 drop_seq(Header) ->
     get_field(Header, drop_seq).
 
+drop_count(Header) ->
+    get_field(Header, drop_count).
+
 purge_infos_limit(Header) ->
     get_field(Header, purge_infos_limit).
 
diff --git a/src/couch/src/couch_db.erl b/src/couch/src/couch_db.erl
index 8718b5b82..e4d16a36b 100644
--- a/src/couch/src/couch_db.erl
+++ b/src/couch/src/couch_db.erl
@@ -42,6 +42,7 @@
     get_db_info/1,
     get_partition_info/2,
     get_del_doc_count/1,
+    get_drop_count/1,
     get_doc_count/1,
     get_epochs/1,
     get_filepath/1,
@@ -579,6 +580,9 @@ get_pid(#db{main_pid = Pid}) ->
 get_del_doc_count(Db) ->
     {ok, couch_db_engine:get_del_doc_count(Db)}.
 
+get_drop_count(Db) ->
+    {ok, couch_db_engine:get_drop_count(Db)}.
+
 get_doc_count(Db) ->
     {ok, couch_db_engine:get_doc_count(Db)}.
 
@@ -619,6 +623,7 @@ get_db_info(Db) ->
     } = Db,
     {ok, DocCount} = get_doc_count(Db),
     {ok, DelDocCount} = get_del_doc_count(Db),
+    {ok, DropCount} = get_drop_count(Db),
     SizeInfo = couch_db_engine:get_size_info(Db),
     DiskVersion = couch_db_engine:get_disk_version(Db),
     Uuid =
@@ -641,6 +646,7 @@ get_db_info(Db) ->
         {engine, couch_db_engine:get_engine(Db)},
         {doc_count, DocCount},
         {doc_del_count, DelDocCount},
+        {drop_count, DropCount},
         {update_seq, get_update_seq(Db)},
         {purge_seq, couch_db_engine:get_purge_seq(Db)},
         {compact_running, Compactor /= nil},
diff --git a/src/couch/src/couch_db_engine.erl 
b/src/couch/src/couch_db_engine.erl
index a07dcc6ac..7a3dd8b32 100644
--- a/src/couch/src/couch_db_engine.erl
+++ b/src/couch/src/couch_db_engine.erl
@@ -194,6 +194,11 @@
 -callback get_del_doc_count(DbHandle :: db_handle()) ->
     DelDocCount :: non_neg_integer().
 
+% The number of tombstones (deleted documents with no content) in the
+% database which have been completely dropped from the database.
+-callback get_drop_count(DbHandle :: db_handle()) ->
+    DropCount :: non_neg_integer().
+
 % This number is reported in the database info properties and
 % as such can be any JSON value.
 -callback get_disk_version(DbHandle :: db_handle()) -> Version :: json().
@@ -679,6 +684,7 @@
     get_engine/1,
     get_compacted_seq/1,
     get_del_doc_count/1,
+    get_drop_count/1,
     get_disk_version/1,
     get_doc_count/1,
     get_epochs/1,
@@ -806,6 +812,10 @@ get_del_doc_count(#db{} = Db) ->
     #db{engine = {Engine, EngineState}} = Db,
     Engine:get_del_doc_count(EngineState).
 
+get_drop_count(#db{} = Db) ->
+    #db{engine = {Engine, EngineState}} = Db,
+    Engine:get_drop_count(EngineState).
+
 get_disk_version(#db{} = Db) ->
     #db{engine = {Engine, EngineState}} = Db,
     Engine:get_disk_version(EngineState).
diff --git a/src/fabric/src/fabric_db_info.erl 
b/src/fabric/src/fabric_db_info.erl
index 5461404c5..08d3747aa 100644
--- a/src/fabric/src/fabric_db_info.erl
+++ b/src/fabric/src/fabric_db_info.erl
@@ -105,6 +105,8 @@ merge_results(Info) ->
                 [{doc_count, lists:sum(X)} | Acc];
             (doc_del_count, X, Acc) ->
                 [{doc_del_count, lists:sum(X)} | Acc];
+            (drop_count, X, Acc) ->
+                [{drop_count, lists:sum(X)} | Acc];
             (compact_running, X, Acc) ->
                 [{compact_running, lists:member(true, X)} | Acc];
             (sizes, X, Acc) ->
diff --git a/test/elixir/test/drop_seq_test.exs 
b/test/elixir/test/drop_seq_test.exs
index daa7e4f0a..85ee3f200 100644
--- a/test/elixir/test/drop_seq_test.exs
+++ b/test/elixir/test/drop_seq_test.exs
@@ -98,10 +98,12 @@ defmodule DropSeqTest do
   defp checkpoint_test_helper(db_name, create_checkpoint_fn, 
update_checkpoint_fn) do
     doc_id = "testdoc"
 
+    assert get_drop_count(db_name) == 0
     drop_seq = update_drop_seq(db_name)
 
     # create something that will create a peer checkpoint
     create_checkpoint_fn.()
+    assert get_drop_count(db_name) == 0
 
     # create a document
     resp = Couch.put("/#{db_name}/#{doc_id}", body: %{})
@@ -114,6 +116,7 @@ defmodule DropSeqTest do
 
     # wait for drop seq to change
     wait_for_drop_seq_change(db_name, drop_seq, update_checkpoint_fn)
+    assert get_drop_count(db_name) == 0
 
     # confirm deleted doc is still in _changes response
     resp = Couch.get("/#{db_name}/_changes")
@@ -127,6 +130,7 @@ defmodule DropSeqTest do
     resp = Couch.get("/#{db_name}/_changes")
     assert resp.status_code == 200
     assert !Enum.member?(get_ids(resp), doc_id)
+    assert get_drop_count(db_name) == 1
   end
 
   defp wait_for_drop_seq_change(db_name, previous_drop_seq, 
update_checkpoint_fn) do
@@ -147,6 +151,12 @@ defmodule DropSeqTest do
     resp.body["results"]
   end
 
+  defp get_drop_count(db_name) do
+    resp = Couch.get("/#{db_name}")
+    assert resp.status_code == 200
+    resp.body["drop_count"]
+  end
+
   defp get_ids(resp) do
     %{:body => %{"results" => results}} = resp
     Enum.map(results, fn result -> result["id"] end)

Reply via email to