22
33#include " openPMD/DatatypeMacros.hpp"
44#include " openPMD/IO/JSON/JSONIOHandlerImpl.hpp"
5+ #include " openPMD/auxiliary/StringManip.hpp"
56
67#include < nlohmann/json.hpp>
78
@@ -16,6 +17,30 @@ ExternalBlockStorageBackend::~ExternalBlockStorageBackend() = default;
1617
1718namespace openPMD
1819{
20+
21+ namespace
22+ {
23+ auto flat_extent (Extent const &e) -> size_t
24+ {
25+ return std::accumulate (
26+ e.begin (), e.end (), 1 , [](size_t left, size_t right) {
27+ return left * right;
28+ });
29+ }
30+
31+ template <typename T>
32+ void read_impl (
33+ internal::ExternalBlockStorageBackend *backend,
34+ nlohmann::json const &external_block,
35+ T *data,
36+ size_t len)
37+ {
38+ auto const &external_ref =
39+ external_block.at (" external_ref" ).get <std::string>();
40+ backend->get (external_ref, data, sizeof (T) * len);
41+ }
42+ } // namespace
43+
1944ExternalBlockStorage::ExternalBlockStorage () = default ;
2045ExternalBlockStorage::ExternalBlockStorage (
2146 std::unique_ptr<internal::ExternalBlockStorageBackend> worker)
@@ -125,25 +150,11 @@ auto ExternalBlockStorage::store(
125150 auto escaped_filesystem_identifier = m_worker->put (
126151 filesystem_identifier.str (),
127152 data,
128- std::accumulate (
129- blockExtent.begin (),
130- blockExtent.end (),
131- sizeof (T),
132- [](size_t left, size_t right) { return left * right; }));
153+ sizeof (T) * flat_extent (blockExtent));
133154 block[" external_ref" ] = escaped_filesystem_identifier;
134155 return index_as_str;
135156}
136157
137- namespace
138- {
139- template <typename T>
140- void read_impl (
141- internal::ExternalBlockStorageBackend *backend,
142- nlohmann::json const &external_block,
143- T *data)
144- {}
145- } // namespace
146-
147158template <typename DatatypeHandling, typename T>
148159void ExternalBlockStorage::read (
149160 std::string const &identifier,
@@ -161,6 +172,43 @@ void ExternalBlockStorage::read(
161172 T *data)
162173{
163174 auto &dataset = fullJsonDataset[path];
175+ if (!DatatypeHandling::template checkDatatype<T>(dataset))
176+ {
177+ throw std::runtime_error (" Inconsistent chunk storage in datatype." );
178+ }
179+ auto external_blocks = dataset[" external_blocks" ];
180+ bool found_a_precise_match = false ;
181+ for (auto it = external_blocks.begin (); it != external_blocks.end (); ++it)
182+ {
183+ auto const &block = it.value ();
184+ try
185+ {
186+ auto const &o = block.at (" offset" ).get <Offset>();
187+ auto const &e = block.at (" extent" ).get <Extent>();
188+ // Look only for exact matches for now
189+ if (o != blockOffset || e != blockExtent)
190+ {
191+ continue ;
192+ }
193+ found_a_precise_match = true ;
194+ read_impl (m_worker.get (), block, data, flat_extent (blockExtent));
195+ break ;
196+ }
197+ catch (nlohmann::json::exception const &e)
198+ {
199+ std::cerr << " [ExternalBlockStorage::read] Could not parse block '"
200+ << it.key () << " '. Original error was:\n "
201+ << e.what ();
202+ }
203+ }
204+ if (!found_a_precise_match)
205+ {
206+ throw std::runtime_error (
207+ " [ExternalBlockStorage::read] Unable to find a precise match for "
208+ " offset " +
209+ auxiliary::vec_as_string (blockOffset) + " and extent " +
210+ auxiliary::vec_as_string (blockExtent));
211+ }
164212}
165213
166214[[nodiscard]] auto ExternalBlockStorage::externalStorageLocation () const
0 commit comments