@@ -143,16 +143,28 @@ inline Link CLASS::top(const Link& link) const NOEXCEPT
143143 return head_.top (link);
144144}
145145
146+ TEMPLATE
147+ inline bool CLASS::exists (const memory_ptr& ptr, const Key& key) const NOEXCEPT
148+ {
149+ return !first (ptr, key).is_terminal ();
150+ }
151+
146152TEMPLATE
147153inline bool CLASS::exists (const Key& key) const NOEXCEPT
148154{
149155 return !first (key).is_terminal ();
150156}
151157
158+ TEMPLATE
159+ inline Link CLASS::first (const memory_ptr& ptr, const Key& key) const NOEXCEPT
160+ {
161+ return first (ptr, head_.top (key), key);
162+ }
163+
152164TEMPLATE
153165inline Link CLASS::first (const Key& key) const NOEXCEPT
154166{
155- return first (get_memory (), head_. top (key), key);
167+ return first (get_memory (), key);
156168}
157169
158170TEMPLATE
@@ -250,14 +262,32 @@ inline bool CLASS::get(const iterator& it, const Link& link,
250262
251263TEMPLATE
252264template <typename Element, if_equal<Element::size, Size>>
253- bool CLASS::set (const Link& link, const Element& element) NOEXCEPT
265+ bool CLASS::set (const memory_ptr& ptr, const Link& link, const Key& key,
266+ const Element& element) NOEXCEPT
254267{
255268 using namespace system ;
256- const auto ptr = body_.get (link);
257269 if (!ptr)
258270 return false ;
259271
260- iostream stream{ *ptr };
272+ const auto start = body::link_to_position (link);
273+ if (is_limited<ptrdiff_t >(start))
274+ return false ;
275+
276+ const auto size = ptr->size ();
277+ const auto position = possible_narrow_and_sign_cast<ptrdiff_t >(start);
278+ if (position > size)
279+ return false ;
280+
281+ // Stream starts at record and the index is skipped for reader convenience.
282+ const auto offset = ptr->offset (start);
283+ if (is_null (offset))
284+ return false ;
285+
286+ // Set element search key.
287+ unsafe_array_cast<uint8_t , key_size>(std::next (offset,
288+ Link::size)) = key;
289+
290+ iostream stream{ offset, size - position };
261291 finalizer sink{ stream };
262292 sink.skip_bytes (index_size);
263293
@@ -267,21 +297,30 @@ bool CLASS::set(const Link& link, const Element& element) NOEXCEPT
267297
268298TEMPLATE
269299template <typename Element, if_equal<Element::size, Size>>
270- inline Link CLASS::set_link (const Element& element) NOEXCEPT
300+ bool CLASS::set (const Link& link, const Key& key,
301+ const Element& element) NOEXCEPT
302+ {
303+ return set (get_memory (), link, key, element);
304+ }
305+
306+ TEMPLATE
307+ template <typename Element, if_equal<Element::size, Size>>
308+ inline Link CLASS::set_link (const Key& key, const Element& element) NOEXCEPT
271309{
272310 Link link{};
273- if (!set_link (link, element))
311+ if (!set_link (link, key, element))
274312 return {};
275313
276314 return link;
277315}
278316
279317TEMPLATE
280318template <typename Element, if_equal<Element::size, Size>>
281- inline bool CLASS::set_link (Link& link, const Element& element) NOEXCEPT
319+ inline bool CLASS::set_link (Link& link, const Key& key,
320+ const Element& element) NOEXCEPT
282321{
283322 link = allocate (element.count ());
284- return set (link, element);
323+ return set (link, key, element);
285324}
286325
287326TEMPLATE
@@ -329,22 +368,33 @@ inline bool CLASS::put(const memory_ptr& ptr, const Link& link, const Key& key,
329368}
330369
331370TEMPLATE
332- bool CLASS::commit (const Link& link, const Key& key) NOEXCEPT
371+ bool CLASS::commit (const memory_ptr& ptr, const Link& link,
372+ const Key& key) NOEXCEPT
333373{
334374 using namespace system ;
335- const auto ptr = body_.get (link);
336375 if (!ptr)
337376 return false ;
338377
339- // Set element search key.
340- unsafe_array_cast<uint8_t , key_size>(std::next (ptr->begin (),
341- Link::size)) = key;
378+ // get element offset (fault)
379+ const auto offset = ptr->offset (body::link_to_position (link));
380+ if (is_null (offset))
381+ return false ;
382+
383+ // // Set element search key.
384+ // unsafe_array_cast<uint8_t, key_size>(std::next(offset,
385+ // Link::size)) = key;
342386
343387 // Commit element to search index (terminal is a valid bucket index).
344- auto & next = unsafe_array_cast<uint8_t , Link::size>(ptr-> begin () );
388+ auto & next = unsafe_array_cast<uint8_t , Link::size>(offset );
345389 return head_.push (link, next, head_.index (key));
346390}
347391
392+ TEMPLATE
393+ bool CLASS::commit (const Link& link, const Key& key) NOEXCEPT
394+ {
395+ return commit (get_memory (), link, key);
396+ }
397+
348398TEMPLATE
349399inline Link CLASS::commit_link (const Link& link, const Key& key) NOEXCEPT
350400{
0 commit comments