From f04f085931c7443269de6b73ef6a8de36ebd4ef7 Mon Sep 17 00:00:00 2001 From: Gabriel Studer <gabriel.studer@unibas.ch> Date: Fri, 16 Feb 2024 16:12:49 +0100 Subject: [PATCH] make removing atoms fast again Removing atoms from huge structures was observed to be super slow. Reason was the removal from the spatial organizer which helps to find atoms based on spatial proximity. The organizer is organized in buckets which occupy a certain volume in space. Removing an element meant to iterate over all buckets and all their items until the atom is found. However, we know the position of the atom and thus can pinpoint the bucket in which its expected to be. The SpatialOrganizer::Remove was therefore overloaded with a version that accepts a position as hint in which bucket to look. If the atom is there, delete and return. If not, call Remove without position hint. --- modules/mol/base/src/impl/entity_impl.cc | 2 +- modules/mol/base/src/spatial_organizer.hh | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/mol/base/src/impl/entity_impl.cc b/modules/mol/base/src/impl/entity_impl.cc index 4d378dbbe..da4000aef 100644 --- a/modules/mol/base/src/impl/entity_impl.cc +++ b/modules/mol/base/src/impl/entity_impl.cc @@ -323,7 +323,7 @@ AtomImplPtr EntityImpl::CreateAtom(const ResidueImplPtr& rp, void EntityImpl::DeleteAtom(const AtomImplPtr& atom) { atom_map_.erase(atom.get()); - atom_organizer_.Remove(atom); + atom_organizer_.Remove(atom, atom->TransformedPos()); } ResidueImplPtr EntityImpl::CreateResidue(const ChainImplPtr& cp, diff --git a/modules/mol/base/src/spatial_organizer.hh b/modules/mol/base/src/spatial_organizer.hh index 413bc6af4..fce132a25 100644 --- a/modules/mol/base/src/spatial_organizer.hh +++ b/modules/mol/base/src/spatial_organizer.hh @@ -113,6 +113,23 @@ public: } } + void Remove(const ITEM& item, const VEC& pos) { + // variation of the above, first try in organizer bucket + // for which you give a hint with pos. If this is successful, + // return. Call naive Remove otherwise + Index indx=gen_index(pos); + typename ItemMap::iterator i = map_.find(indx); + if(i != map_.end()) { + for (size_t j=0; j<i->second.size(); ++j) { + if (i->second[j].item==item) { + i->second.erase(i->second.begin()+j); + return; + } + } + } + Remove(item); + } + bool HasWithin(const VEC& pos, Real dist) const { Real dist2=dist*dist; Index imin = Index::Max(min_, gen_index(pos-VEC(dist,dist,dist))); -- GitLab