@@ -47,6 +47,26 @@ state(File&& df_, File&& kf_, File&& lf_,
4747 " File requirements not met" );
4848}
4949
50+ template <class Hasher , class File >
51+ basic_store<Hasher, File>::state::
52+ state (File&& df_, File&& kf_,
53+ path_type const & dp_, path_type const & kp_,
54+ detail::key_file_header const & kh_)
55+ : df(std::move(df_))
56+ , kf(std::move(kf_))
57+ , dp(dp_)
58+ , kp(kp_)
59+ , hasher(kh_.salt)
60+ , p0(kh_.key_size, " p0" )
61+ , p1(kh_.key_size, " p1" )
62+ , c1(kh_.key_size, kh_.block_size, " c1" )
63+ , kh(kh_)
64+ {
65+ static_assert (is_File<File>::value,
66+ " File requirements not met" );
67+ }
68+
69+
5070// ------------------------------------------------------------------------------
5171
5272template <class Hasher , class File >
@@ -214,6 +234,92 @@ open(
214234 ec, args...);
215235}
216236
237+ template <class Hasher , class File >
238+ template <class ... Args>
239+ void
240+ basic_store<Hasher, File>::
241+ open_read_only (
242+ path_type const & dat_path,
243+ path_type const & key_path,
244+ error_code& ec,
245+ Args&&... args)
246+ {
247+ static_assert (is_Hasher<Hasher>::value,
248+ " Hasher requirements not met" );
249+ using namespace detail ;
250+ BOOST_ASSERT (! is_open ());
251+ ec_ = {};
252+ ecb_.store (false );
253+
254+ File df (args...);
255+ File kf (args...);
256+ df.open (file_mode::read, dat_path, ec);
257+ if (ec)
258+ return ;
259+ kf.open (file_mode::read, key_path, ec);
260+ if (ec)
261+ return ;
262+
263+ dat_file_header dh;
264+ read (df, dh, ec);
265+ if (ec)
266+ return ;
267+ verify (dh, ec);
268+ if (ec)
269+ return ;
270+
271+ key_file_header kh;
272+ read (kf, kh, ec);
273+ if (ec)
274+ return ;
275+ verify<Hasher>(kh, ec);
276+ if (ec)
277+ return ;
278+
279+ verify<Hasher>(dh, kh, ec);
280+ if (ec)
281+ return ;
282+
283+ boost::optional<state> s;
284+ s.emplace (std::move (df), std::move (kf),
285+ dat_path, key_path, kh);
286+ thresh_ = std::max<std::size_t >(65536UL ,
287+ kh.load_factor * kh.capacity );
288+ frac_ = thresh_ / 2 ;
289+ buckets_ = kh.buckets ;
290+ modulus_ = ceil_pow2 (kh.buckets );
291+ // VFALCO TODO This could be better
292+ if (buckets_ < 1 )
293+ {
294+ ec = error::short_key_file;
295+ return ;
296+ }
297+ s_.emplace (std::move (*s));
298+ open_ = true ;
299+ read_only_ = true ;
300+ ctx_->insert (*this );
301+ }
302+
303+ template <class Hasher , class File >
304+ template <class ... Args>
305+ void
306+ basic_store<Hasher, File>::
307+ open_read_only (
308+ path_type const & dir_path,
309+ error_code& ec,
310+ Args&&... args){
311+ BOOST_ASSERT (boost::filesystem::exists (dir_path));
312+
313+ boost::filesystem::path fs_dir_path (dir_path);
314+
315+ boost::filesystem::path dat_path =
316+ fs_dir_path / detail::default_dat_file ();
317+ boost::filesystem::path key_path =
318+ fs_dir_path / detail::default_key_file ();
319+
320+ open_read_only (dat_path.string (), key_path.string (), ec, args...);
321+ }
322+
217323template <class Hasher , class File >
218324void
219325basic_store<Hasher, File>::
@@ -223,6 +329,10 @@ close(error_code& ec)
223329 {
224330 open_ = false ;
225331 ctx_->erase (*this );
332+
333+ if (read_only_)
334+ return ;
335+
226336 if (! s_->p1 .empty ())
227337 {
228338 std::size_t work;
@@ -302,6 +412,7 @@ insert(
302412 using namespace detail ;
303413 using namespace std ::chrono;
304414 BOOST_ASSERT (is_open ());
415+ BOOST_ASSERT (!is_read_only ());
305416 if (ecb_)
306417 {
307418 ec = ec_;
@@ -776,6 +887,9 @@ flush()
776887 using namespace std ::chrono;
777888 using namespace detail ;
778889
890+ if (is_read_only ())
891+ return ;
892+
779893#if NUDB_DEBUG_LOG
780894 beast::unit_test::dstream dout{std::cout};
781895#endif
0 commit comments