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)