ccia_code_samples icon indicating copy to clipboard operation
ccia_code_samples copied to clipboard

6.11 doesn't compile

Open spaceyjase opened this issue 5 years ago • 2 comments

typedef typename bucket_data::iterator bucket_iterator;
bucket_iterator find_entry_for(Key const& key) const
{
  return std::find_if(data.begin(), data.end(), [&](bucket_value const& item) {
    return item.first == key;
  });
}

This returns a const_iterator, the compiler issues an error because it can't convert between the two.

spaceyjase avatar Mar 22 '19 10:03 spaceyjase

Yes, I modified some codes as below. Hope can help :)

template<typename Key, typename Value, typename Hash=std::hash<Key> >
class threadsafe_lookup_table {
private:
	class bucket_type {
	public:
		using bucket_value = std::pair<Key, Value>;
		using bucket_data = std::list<bucket_value>;
		using bucket_iterator = typename std::list<bucket_value>::iterator;

		// properties
		bucket_data data;
		mutable boost::shared_mutex mutex;

		bucket_iterator find_entry_for(Key const& key) {
			return std::find_if(std::begin(data), std::end(data),
					[&](bucket_value const& item) { return item.first == key; });
		}
	public:
		Value value_for(Key const& key, Value const& default_val) {
			boost::shared_lock_guard<boost::shared_mutex> lock(mutex);
			bucket_iterator const found_entry = find_entry_for(key);
			return ((found_entry == data.end()) ? default_val : found_entry->second);
		}

		void add_or_update_mapping(Key const& key, Value const& value) {
			boost::shared_lock_guard<boost::shared_mutex> lock(mutex);
			bucket_iterator const found_entry = find_entry_for(key);
			if (found_entry == data.end()) {
				data.emplace_back(std::make_pair(key, value));
			} else {
				found_entry->second = value;
			}
		}
		void remove_mapping(Key const& key) {
			boost::shared_lock_guard<boost::shared_mutex> lock(mutex);
			bucket_iterator const found_entry = find_entry_for(key);
			if (found_entry != data.end()) {
				data.erase(found_entry);
			}
		}
	};

	std::vector<std::unique_ptr<bucket_type> > buckets;
	Hash hasher;

	bucket_type& get_bucket(Key const& key) const {
		std::size_t const bucket_index = hasher(key) % buckets.size();
		return *buckets[bucket_index];
	}

public:
	threadsafe_lookup_table(unsigned num_buckets = 19, Hash const& hash_=Hash()) :
		buckets(num_buckets), hasher(hash_) {
		for (unsigned i=0; i < num_buckets; i++) {
			buckets[i].reset(new bucket_type);
		}
	}
	threadsafe_lookup_table(const threadsafe_lookup_table&) = delete;
	threadsafe_lookup_table& operator=(const threadsafe_lookup_table&) = delete;

	Value value_for(Key const& key, Value const& default_value = Value()) const {
		return get_bucket(key).value_for(key, default_value);
	}

	void add_or_update_mapping(Key const& key, Value const& value) {
		get_bucket(key).add_or_update_mapping(key, value);
	}
	void remove_mapping(Key const& key) {
		get_bucket(key).remove_mapping(key);
	}
	std::map<Key, Value> get_map() {
		std::vector<boost::unique_lock<boost::shared_mutex> > locks;
		for (unsigned i = 0; i < buckets.size(); ++i) {
			locks.emplace_back(boost::unique_lock<boost::shared_mutex> (buckets[i]->mutex));
		}
		std::map<Key, Value> res;
		for(unsigned i = 0; i < buckets.size(); ++i) {
			for(auto it = std::begin(buckets[i]->data); it != std::end(buckets[i]->data); ++it) {
				res.insert(*it);
			}
		}
		return res;
	}
};

pvthuyet avatar Aug 08 '19 10:08 pvthuyet

Happy three year anniversary!

A quick solution would be to remove const from the end of find_entry_for(), so this...

https://github.com/anthonywilliams/ccia_code_samples/blob/6e7ae1d66dbd2e8f1ad18a5cf5c6d25a37b92388/listings/listing_6.11.cpp#L23

...would become this...

https://github.com/anthonywilliams/ccia_code_samples/blob/e893b0c531110546abf2d2677c1144ea3e290a3d/listings/listing_6.11.cpp#L23

https://github.com/anthonywilliams/ccia_code_samples/compare/main...ITHelpDec:ccia_code_samples:patch-4

A nicer alternative would be to respect const-ness by making tweaks elsewhere in the code, but I've raised a PR here to help anyone else that might be looking for an answer in the meantime.

ITHelpDec avatar May 26 '23 23:05 ITHelpDec