pstore2
db_archive.hpp
Go to the documentation of this file.
1 //===- include/pstore/core/db_archive.hpp -----------------*- mode: C++ -*-===//
2 //* _ _ _ _ *
3 //* __| | |__ __ _ _ __ ___| |__ (_)_ _____ *
4 //* / _` | '_ \ / _` | '__/ __| '_ \| \ \ / / _ \ *
5 //* | (_| | |_) | | (_| | | | (__| | | | |\ V / __/ *
6 //* \__,_|_.__/ \__,_|_| \___|_| |_|_| \_/ \___| *
7 //* *
8 //===----------------------------------------------------------------------===//
9 //
10 // Part of the pstore project, under the Apache License v2.0 with LLVM Exceptions.
11 // See https://github.com/SNSystems/pstore/blob/master/LICENSE.txt for license
12 // information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //===----------------------------------------------------------------------===//
19 
20 #ifndef PSTORE_CORE_DB_ARCHIVE_HPP
21 #define PSTORE_CORE_DB_ARCHIVE_HPP
22 
25 #include "pstore/support/error.hpp"
26 
27 namespace pstore {
28  namespace serialize {
30  namespace archive {
31 
32  // *************************************
33  // * d a t a b a s e _ w r i t e r *
34  // *************************************
35  namespace details {
36 
38  public:
40 
41  explicit constexpr database_writer_policy (transaction_base & trans) noexcept
42  : transaction_ (trans) {}
43 
47  template <typename Ty>
48  auto put (Ty const & value) -> result_type {
49  std::shared_ptr<Ty> ptr;
50  auto addr = typed_address<Ty>::null ();
51  std::tie (ptr, addr) = transaction_.template alloc_rw<Ty> ();
52  *ptr = value;
53  return addr.to_address ();
54  }
55 
56  template <typename Span>
57  auto putn (Span sp) -> result_type {
58  using element_type =
59  typename std::remove_const<typename Span::element_type>::type;
60 
61  std::shared_ptr<element_type> ptr;
62  auto addr = typed_address<element_type>::null ();
63  std::tie (ptr, addr) = transaction_.template alloc_rw<element_type> (
64  unsigned_cast (sp.size ()));
65  std::copy (std::begin (sp), std::end (sp), ptr.get ());
66  return addr.to_address ();
67  }
68 
69  void flush () noexcept {}
70 
71  private:
73  transaction_base & transaction_;
74  };
75 
76  } // namespace details
77 
78  class database_writer final : public writer_base<details::database_writer_policy> {
80 
81  public:
86  : writer_base<policy> (policy{transaction}) {}
87  };
88 
94  }
95 
96 
97  // *************************************
98  // * d a t a b a s e _ r e a d e r *
99  // *************************************
100 
103  public:
108  database_reader (pstore::database const & db, pstore::address const addr) noexcept
109  : db_ (db)
110  , addr_ (addr) {}
111 
112  pstore::database const & get_db () const noexcept { return db_; }
113  pstore::address get_address () const noexcept { return addr_; }
114  void skip (std::size_t const distance) noexcept { addr_ += distance; }
115 
123  template <typename Ty, typename = typename std::enable_if<
124  std::is_standard_layout<Ty>::value>::type>
125  void get (Ty & v);
126 
132  template <typename SpanType,
133  typename = typename std::enable_if<std::is_standard_layout<
134  typename SpanType::element_type>::value>::type>
135  void getn (SpanType span);
136 
137  private:
138  database const & db_;
139  address addr_;
140  };
141 
142  // get
143  // ~~~
144  template <typename Ty, typename>
145  void database_reader::get (Ty & v) {
146 
147  auto const extra_for_alignment = calc_alignment (addr_.absolute (), alignof (Ty));
148  PSTORE_ASSERT (extra_for_alignment < sizeof (Ty));
149  addr_ += extra_for_alignment;
150  // Load the data.
151  auto result = db_.getro (typed_address<Ty> (addr_));
152  addr_ += sizeof (Ty);
153  // Copy to the destination.
154  new (&v) Ty (*result);
155  }
156 
157  // getn
158  // ~~~~
159  template <typename SpanType, typename>
160  void database_reader::getn (SpanType span) {
161  using element_type = typename SpanType::element_type;
162 
163  // Adjust addr_ so that it is correctly aligned for element_type.
164  auto const extra_for_alignment =
165  calc_alignment (addr_.absolute (), alignof (element_type));
166  PSTORE_ASSERT (extra_for_alignment < sizeof (element_type));
167  addr_ += extra_for_alignment;
168 
169  // Load the data.
170  auto const size = unsigned_cast (span.size_bytes ());
171  auto src = db_.getro (typed_address<std::uint8_t> (addr_), size);
172  addr_ += size;
173 
174  // Copy to the destination span.
175  auto first = src.get ();
176  std::copy (first, first + size, reinterpret_cast<std::uint8_t *> (span.data ()));
177  }
178 
187  pstore::address const addr) noexcept {
188  return {db, addr};
189  }
190  } // namespace archive
191  } // namespace serialize
192 } // namespace pstore
193 #endif // PSTORE_CORE_DB_ARCHIVE_HPP
The basic archive reader and writer types.
An archive-reader which reads data from a database.
Definition: db_archive.hpp:102
The base class for archive-writer objects.
Definition: archive.hpp:139
Definition: address.hpp:81
constexpr Ty calc_alignment(Ty const v, std::size_t const align) noexcept
Calculate the value that must be added to p v in order that it has the alignment given by align...
Definition: aligned.hpp:86
auto put(Ty const &value) -> result_type
Writes an instance of a standard-layout type T to the database.
Definition: db_archive.hpp:48
The data store transaction class.
Definition: transaction.hpp:191
Definition: address.hpp:231
database_reader(pstore::database const &db, pstore::address const addr) noexcept
Constructs the reader using an input database and an address.
Definition: db_archive.hpp:108
void getn(SpanType span)
Reads a span of a trivial type from the current store address.
Definition: db_archive.hpp:160
auto make_writer(transaction_base &transaction) noexcept -> database_writer
A convenience function which simplifies the construction of a database_writer instance if the caller ...
Definition: db_archive.hpp:92
Definition: print.cpp:18
void get(Ty &v)
Reads a single instance of a standard-layout type Ty from the current store address.
Definition: db_archive.hpp:145
database_reader make_reader(pstore::database const &db, pstore::address const addr) noexcept
A convenience function which provides symmetry with the make_writer() function.
Definition: db_archive.hpp:186
Definition: nonpod2.cpp:40
Definition: database.hpp:40
Definition: db_archive.hpp:78
Provides an pstore-specific error codes and a suitable error category for them.
database_writer(transaction_base &transaction)
Constructs the writer using the transaction.
Definition: db_archive.hpp:85
The database transaction class.
Definition: transaction.hpp:43