diff options
3 files changed, 18 insertions, 6 deletions
diff --git a/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.hpp b/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.hpp index 3dcc0df477d..07f8077ae97 100644 --- a/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.hpp +++ b/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.hpp @@ -42,9 +42,9 @@ template <typename EntryT, typename RefT> void MultiValueMapping<EntryT,RefT>::replace(uint32_t docId, ConstArrayRef values) { - ConstArrayRef oldValues = _store.get(_indices[docId]); + auto oldValues = _store.get_writable(_indices[docId]); assert(oldValues.size() == values.size()); - EntryT *dst = const_cast<EntryT *>(&oldValues[0]); + EntryT *dst = &oldValues[0]; for (auto &src : values) { *dst = src; ++dst; diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_index_base.cpp b/searchlib/src/vespa/searchlib/tensor/hnsw_index_base.cpp index bd53013b94d..0ec0348a398 100644 --- a/searchlib/src/vespa/searchlib/tensor/hnsw_index_base.cpp +++ b/searchlib/src/vespa/searchlib/tensor/hnsw_index_base.cpp @@ -63,11 +63,11 @@ void HnswIndexBase::set_link_array(uint32_t docid, uint32_t level, const LinkArrayRef& links) { auto links_ref = _links.add(links); - auto levels = get_level_array(docid); - // TODO: Add function to ArrayStore that returns mutable array ref, eg. get_writable() - auto mutable_levels = vespalib::unconstify(levels); + // TODO: Add memory barrier? + auto node_ref = _node_refs[docid]; + auto levels = _nodes.get_writable(node_ref); // TODO: Make this change atomic. - mutable_levels[level] = links_ref; + levels[level] = links_ref; } bool diff --git a/vespalib/src/vespa/vespalib/datastore/array_store.h b/vespalib/src/vespa/vespalib/datastore/array_store.h index d5fef404a43..4c289c04564 100644 --- a/vespalib/src/vespa/vespalib/datastore/array_store.h +++ b/vespalib/src/vespa/vespalib/datastore/array_store.h @@ -25,6 +25,7 @@ template <typename EntryT, typename RefT = EntryRefT<19> > class ArrayStore { public: + using ArrayRef = vespalib::ArrayRef<EntryT>; using ConstArrayRef = vespalib::ConstArrayRef<EntryT>; using DataStoreType = DataStoreT<RefT>; using SmallArrayType = BufferType<EntryT>; @@ -82,6 +83,17 @@ public: return getLargeArray(internalRef); } } + + /** + * Returns a writeable reference to the given array. + * + * NOTE: Use with care if reader threads are accessing arrays at the same time. + * If so, replacing an element in the array should be an atomic operation. + */ + ArrayRef get_writable(EntryRef ref) { + return vespalib::unconstify(get(ref)); + } + void remove(EntryRef ref); ICompactionContext::UP compactWorst(bool compactMemory, bool compactAddressSpace); vespalib::MemoryUsage getMemoryUsage() const { return _store.getMemoryUsage(); } |