You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2020/06/05 21:38:18 UTC
[couchdb] 03/05: Needs to be split for moving function
This is an automated email from the ASF dual-hosted git repository.
davisp pushed a commit to branch prototype/fdb-layer-db-version-as-vstamps
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 5b752b8b8e25642a95f566f16bad2a4d02b98bd5
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Fri Jun 5 15:39:03 2020 -0500
Needs to be split for moving function
---
src/fabric/src/fabric2_fdb.erl | 116 ++++++++++++++++++-----------------------
1 file changed, 52 insertions(+), 64 deletions(-)
diff --git a/src/fabric/src/fabric2_fdb.erl b/src/fabric/src/fabric2_fdb.erl
index 700b53b..c5d8bfc 100644
--- a/src/fabric/src/fabric2_fdb.erl
+++ b/src/fabric/src/fabric2_fdb.erl
@@ -1252,6 +1252,39 @@ load_validate_doc_funs(#{} = Db) ->
}.
+ensure_current(Db) ->
+ ensure_current(Db, true).
+
+
+ensure_current(#{} = Db0, CheckDbVersion) ->
+ require_transaction(Db0),
+ ok = check_metadata_version(Db0),
+
+ if not CheckDbVersion -> ok; true ->
+ ok = check_db_version(Db0)
+ end,
+
+ % Don't update check_current_ts if it doesn't exist
+ Db2 = case maps:is_key(check_current_ts, Db0) of
+ true ->
+ Now = erlang:monotonic_time(millisecond),
+ Db1 = Db0#{check_current_ts := Now},
+ fabric2_server:maybe_update(Db1),
+ Db1;
+ false ->
+ Db0
+ end,
+
+ case maps:get(security_fun, Db2) of
+ SecurityFun when is_function(SecurityFun, 2) ->
+ #{security_doc := SecDoc} = Db2,
+ ok = SecurityFun(Db2, SecDoc),
+ Db2#{security_fun := undefined};
+ undefined ->
+ Db2
+ end.
+
+
bump_metadata_version(Tx) ->
% The 14 zero bytes is pulled from the PR for adding the
% metadata version key. Not sure why 14 bytes when version
@@ -1266,26 +1299,15 @@ check_metadata_version(#{} = Db) ->
} = Db,
AlreadyChecked = get(?PDICT_CHECKED_MD_IS_CURRENT),
- if AlreadyChecked == true -> {current, Db}; true ->
- case erlfdb:wait(erlfdb:get_ss(Tx, ?METADATA_VERSION_KEY)) of
- Version ->
- put(?PDICT_CHECKED_MD_IS_CURRENT, true),
- % We want to set a read conflict on the db version as we'd want
- % to conflict with any writes to this particular db. However
- % during db creation db prefix might not exist yet so we don't
- % add a read-conflict on it then.
- case maps:get(db_prefix, Db, not_found) of
- not_found ->
- ok;
- <<_/binary>> = DbPrefix ->
- DbVerKey = erlfdb_tuple:pack({?DB_VERSION}, DbPrefix),
- erlfdb:add_read_conflict_key(Tx, DbVerKey)
- end,
- {current, Db};
- NewVersion ->
- {stale, Db#{md_version := NewVersion}}
- end
- end.
+ if AlreadyChecked == true -> ok; true ->
+ CurrVersion = erlfdb:wait(erlfdb:get_ss(Tx, ?METADATA_VERSION_KEY)),
+ if CurrVersion == Version -> ok; true ->
+ fabric2_server:maybe_remove(Db),
+ throw({?MODULE, reopen})
+ end,
+ put(?PDICT_CHECKED_MD_IS_CURRENT, true)
+ end,
+ ok.
bump_db_version(#{} = Db) ->
@@ -1302,7 +1324,7 @@ bump_db_version(#{} = Db) ->
ok.
-check_db_version(#{} = Db, CheckDbVersion) ->
+check_db_version(#{} = Db) ->
#{
tx := Tx,
db_prefix := DbPrefix,
@@ -1310,16 +1332,16 @@ check_db_version(#{} = Db, CheckDbVersion) ->
} = Db,
AlreadyChecked = get(?PDICT_CHECKED_DB_IS_CURRENT),
- if not CheckDbVersion orelse AlreadyChecked == true -> current; true ->
+ if AlreadyChecked -> ok; true ->
DbVersionKey = erlfdb_tuple:pack({?DB_VERSION}, DbPrefix),
- case erlfdb:wait(erlfdb:get(Tx, DbVersionKey)) of
- DbVersion ->
- put(?PDICT_CHECKED_DB_IS_CURRENT, true),
- current;
- _NewDBVersion ->
- stale
- end
- end.
+ CurrVersion = erlfdb:wait(erlfdb:get(Tx, DbVersionKey)),
+ if CurrVersion == DbVersion -> ok; true ->
+ fabric2_server:maybe_remove(Db),
+ throw({?MODULE, reopen})
+ end,
+ put(?PDICT_CHECKED_DB_IS_CURRENT, true)
+ end,
+ ok.
soft_delete_db(Db) ->
@@ -1856,40 +1878,6 @@ require_transaction(#{} = _Db) ->
erlang:error(transaction_required).
-ensure_current(Db) ->
- ensure_current(Db, true).
-
-
-ensure_current(#{} = Db0, CheckDbVersion) ->
- require_transaction(Db0),
- Db3 = case check_metadata_version(Db0) of
- {current, Db1} ->
- Db1;
- {stale, Db1} ->
- case check_db_version(Db1, CheckDbVersion) of
- current ->
- % If db version is current, update cache with the latest
- % metadata so other requests can immediately see the
- % refreshed db handle.
- Now = erlang:monotonic_time(millisecond),
- Db2 = Db1#{check_current_ts := Now},
- fabric2_server:maybe_update(Db2),
- Db2;
- stale ->
- fabric2_server:maybe_remove(Db1),
- throw({?MODULE, reopen})
- end
- end,
- case maps:get(security_fun, Db3) of
- SecurityFun when is_function(SecurityFun, 2) ->
- #{security_doc := SecDoc} = Db3,
- ok = SecurityFun(Db3, SecDoc),
- Db3#{security_fun := undefined};
- undefined ->
- Db3
- end.
-
-
check_db_instance(undefined) ->
undefined;