From 56bdbc73f05e5450ff9c36f8e369f2399d113641 Mon Sep 17 00:00:00 2001 From: Adam Kocoloski Date: Fri, 2 Jul 2010 10:23:14 -0400 Subject: failover to reading dbs.couch directly when ets is MIA --- src/mem3.erl | 17 +++++++++-------- src/mem3_util.erl | 21 ++++++++++++++++++++- 2 files changed, 29 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/mem3.erl b/src/mem3.erl index 5116f008..5610f085 100644 --- a/src/mem3.erl +++ b/src/mem3.erl @@ -52,12 +52,13 @@ nodes() -> shards(DbName) when is_list(DbName) -> shards(list_to_binary(DbName)); shards(DbName) -> - case ets:lookup(partitions, DbName) of + try ets:lookup(partitions, DbName) of [] -> - % TODO fall back to checking dbs.couch directly - erlang:error(database_does_not_exist); + mem3_util:load_shards_from_disk(DbName); Else -> Else + catch error:badarg -> + mem3_util:load_shards_from_disk(DbName) end. -spec shards(DbName::iolist(), DocId::binary()) -> [#shard{}]. @@ -74,14 +75,14 @@ shards(DbName, DocId) -> range = ['$1','$2'], ref = '_' }, - % TODO these conditions assume A < B, which we don't require Conditions = [{'<', '$1', HashKey}, {'=<', HashKey, '$2'}], - case ets:select(partitions, [{Head, Conditions, ['$_']}]) of + try ets:select(partitions, [{Head, Conditions, ['$_']}]) of [] -> - % TODO fall back to checking dbs.couch directly - erlang:error(database_does_not_exist); + mem3_util:load_shards_from_disk(DbName, DocId); Shards -> Shards + catch error:badarg -> + mem3_util:load_shards_from_disk(DbName, DocId) end. -spec choose_shards(DbName::iolist(), Options::list()) -> [#shard{}]. @@ -89,7 +90,7 @@ choose_shards(DbName, Options) when is_list(DbName) -> choose_shards(list_to_binary(DbName), Options); choose_shards(DbName, Options) -> try shards(DbName) - catch error:database_does_not_exist -> + catch error:E when E==database_does_not_exist; E==badarg -> Nodes = mem3:nodes(), NodeCount = length(Nodes), N = mem3_util:n_val(couch_util:get_value(n, Options), NodeCount), diff --git a/src/mem3_util.erl b/src/mem3_util.erl index b05faa15..e58bbd4c 100644 --- a/src/mem3_util.erl +++ b/src/mem3_util.erl @@ -2,7 +2,8 @@ -author('brad@cloudant.com'). -export([hash/1, name_shard/1, create_partition_map/4, build_shards/2, - n_val/2, to_atom/1, to_integer/1, write_db_doc/1, delete_db_doc/1]). + n_val/2, to_atom/1, to_integer/1, write_db_doc/1, delete_db_doc/1, + load_shards_from_disk/1, load_shards_from_disk/2]). -define(RINGTOP, 2 bsl 31). % CRC32 space @@ -114,3 +115,21 @@ n_val(N, NodeCount) when N > NodeCount -> NodeCount; n_val(N, _) -> N. + +load_shards_from_disk(DbName) when is_binary(DbName) -> + {ok, Db} = couch_db:open(<<"dbs">>, []), + try load_shards_from_db(Db, DbName) after couch_db:close(Db) end. + +load_shards_from_db(#db{} = ShardDb, DbName) -> + case couch_db:open_doc(ShardDb, DbName, []) of + {ok, #doc{body = {Props}}} -> + ?LOG_INFO("dbs cache miss for ~s", [DbName]), + build_shards(DbName, Props); + {not_found, _} -> + erlang:error(database_does_not_exist) + end. + +load_shards_from_disk(DbName, DocId)-> + Shards = load_shards_from_disk(DbName), + HashKey = hash(DocId), + [S || #shard{range = [B,E]} = S <- Shards, B < HashKey, HashKey =< E]. -- cgit v1.2.3