Author Topic: iterator invalidation on insert and erase  (Read 67040 times)

sodapop

  • Newbie
  • *
  • Posts: 8
    • View Profile
iterator invalidation on insert and erase
« on: March 04, 2014, 07:24:44 PM »
Does the jss::concurrent_map handle the issue with iterator invalidation upon calling insert or erase?

Anthony Williams

  • Administrator
  • Full Member
  • *****
  • Posts: 103
    • View Profile
    • just::thread C++ Thread Library
Re: iterator invalidation on insert and erase
« Reply #1 on: March 05, 2014, 09:20:37 AM »
Does the jss::concurrent_map handle the issue with iterator invalidation upon calling insert or erase?

Yes. Iterators remain valid until they are destroyed. If you compare an iterator to a deleted node to another iterator then you get a jss::concurrent_modification exception thrown unless you anchored one of the iterators (by calling anchor() on it).

sodapop

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: iterator invalidation on insert and erase
« Reply #2 on: March 05, 2014, 05:05:33 PM »
Here as well, we could use some more documentation and explaination of how to handle this situation while iterating several million records such that we can skip the node if it has beeen deleted.

Anthony Williams

  • Administrator
  • Full Member
  • *****
  • Posts: 103
    • View Profile
    • just::thread C++ Thread Library
Re: iterator invalidation on insert and erase
« Reply #3 on: March 05, 2014, 05:34:46 PM »
Here as well, we could use some more documentation and explaination of how to handle this situation while iterating several million records such that we can skip the node if it has beeen deleted.

Iteration automatically skips deleted nodes. If you hang on to your iterator for too long, then another thread might delete the element, but the iterator will still remain valid, can still be dereferenced and still used as a normal iterator. The following code "just works":

Code: [Select]
jss::concurrent_map<int,unsigned> map;
for(jss::concurrent_map<int,unsigned>::iterator it=map.begin();end=map.end();it!=end;++it){
  do_something_with(*it);
}

If the element is deleted after you obtained an iterator to it then you can detect this by calling it->is_deleted_node() but in most cases this isn't necessary --- just proceeding as normal will behave as-if the iteration was done immediately prior to the delete.