您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

242 行
11 KiB

#ifndef STORM_STORAGE_BITVECTORHASHMAP_H_
#define STORM_STORAGE_BITVECTORHASHMAP_H_
#include <cstdint>
#include <functional>
#include "src/storage/BitVector.h"
namespace storm {
namespace storage {
/*!
* This class represents a hash-map whose keys are bit vectors. The value type is arbitrary. Currently, only
* queries and insertions are supported. Also, the keys must be bit vectors with a length that is a multiple of
* 64.
*/
template<typename ValueType, typename Hash1 = std::hash<storm::storage::BitVector>, class Hash2 = storm::storage::NonZeroBitVectorHash>
class BitVectorHashMap {
public:
class BitVectorHashMapIterator {
public:
/*! Creates an iterator that points to the bucket with the given index in the given map.
*
* @param map The map of the iterator.
* @param indexIt An iterator to the index of the bucket the iterator points to.
*/
BitVectorHashMapIterator(BitVectorHashMap const& map, BitVector::const_iterator indexIt);
// Methods to compare two iterators.
bool operator==(BitVectorHashMapIterator const& other);
bool operator!=(BitVectorHashMapIterator const& other);
// Methods to move iterator forward.
BitVectorHashMapIterator& operator++(int);
BitVectorHashMapIterator& operator++();
// Method to retrieve the currently pointed-to bit vector and its mapped-to value.
std::pair<storm::storage::BitVector, ValueType> operator*() const;
private:
// The map this iterator refers to.
BitVectorHashMap const& map;
// An iterator to the bucket this iterator points to.
BitVector::const_iterator indexIt;
};
typedef BitVectorHashMapIterator const_iterator;
/*!
* Creates a new hash map with the given bucket size and initial size.
*
* @param bucketSize The size of the buckets that this map can hold. This value must be a multiple of 64.
* @param initialSize The number of buckets that is initially available.
* @param loadFactor The load factor that determines at which point the size of the underlying storage is
* increased.
*/
BitVectorHashMap(uint64_t bucketSize = 64, uint64_t initialSize = 1000, double loadFactor = 0.75);
/*!
* Searches for the given key in the map. If it is found, the mapped-to value is returned. Otherwise, the
* key is inserted with the given value.
*
* @param key The key to search or insert.
* @param value The value that is inserted if the key is not already found in the map.
* @return The found value if the key is already contained in the map and the provided new value otherwise.
*/
ValueType findOrAdd(storm::storage::BitVector const& key, ValueType const& value);
/*!
* Sets the given key value pain in the map. If the key is found in the map, the corresponding value is
* overwritten with the given value. Otherwise, the key is inserted with the given value.
*
* @param key The key to search or insert.
* @param value The value to set.
*/
void setOrAdd(storm::storage::BitVector const& key, ValueType const& value);
/*!
* Searches for the given key in the map. If it is found, the mapped-to value is returned. Otherwise, the
* key is inserted with the given value.
*
* @param key The key to search or insert.
* @param value The value that is inserted if the key is not already found in the map.
* @return A pair whose first component is the found value if the key is already contained in the map and
* the provided new value otherwise and whose second component is the index of the bucket into which the key
* was inserted.
*/
std::pair<ValueType, std::size_t> findOrAddAndGetBucket(storm::storage::BitVector const& key, ValueType const& value);
/*!
* Sets the given key value pain in the map. If the key is found in the map, the corresponding value is
* overwritten with the given value. Otherwise, the key is inserted with the given value.
*
* @param key The key to search or insert.
* @param value The value to set.
* @return The index of the bucket into which the key was inserted.
*/
std::size_t setOrAddAndGetBucket(storm::storage::BitVector const& key, ValueType const& value);
/*!
* Retrieves the key stored in the given bucket (if any) and the value it is mapped to.
*
* @param bucket The index of the bucket.
* @return The content and value of the named bucket.
*/
std::pair<storm::storage::BitVector, ValueType> getBucketAndValue(std::size_t bucket) const;
/*!
* Retrieves the value associated with the given key (if any). If the key does not exist, the behaviour is
* undefined.
*
* @return The value associated with the given key (if any).
*/
ValueType getValue(storm::storage::BitVector const& key) const;
/*!
* Checks if the given key is already contained in the map.
*
* @param key The key to search
* @return True if the key is already contained in the map
*/
bool contains(storm::storage::BitVector const& key) const;
/*!
* Retrieves an iterator to the elements of the map.
*
* @return The iterator.
*/
const_iterator begin() const;
/*!
* Retrieves an iterator that points one past the elements of the map.
*
* @return The iterator.
*/
const_iterator end() const;
/*!
* Retrieves the size of the map in terms of the number of key-value pairs it stores.
*
* @return The size of the map.
*/
std::size_t size() const;
/*!
* Retrieves the capacity of the underlying container.
*
* @return The capacity of the underlying container.
*/
std::size_t capacity() const;
/*!
* Performs a remapping of all values stored by applying the given remapping.
*
* @param remapping The remapping to apply.
*/
void remap(std::function<ValueType(ValueType const&)> const& remapping);
private:
/*!
* Retrieves whether the given bucket holds a value.
*
* @param bucket The bucket to check.
* @return True iff the bucket is occupied.
*/
bool isBucketOccupied(uint_fast64_t bucket) const;
/*!
* Searches for the bucket with the given key.
*
* @param key The key to search for.
* @return A pair whose first component indicates whether the key is already contained in the map and whose
* second component indicates in which bucket the key is stored.
*/
std::pair<bool, std::size_t> findBucket(storm::storage::BitVector const& key) const;
/*!
* Searches for the bucket into which the given key can be inserted. If no empty bucket can be found, the
* size of the underlying data structure is increased.
*
* @param key The key to search for.
* @param increaseStorage A flag indicating whether the storage should be increased if no bucket can be found.
* @return A tuple whose first component indicates whether the key is already contained in the map, whose
* second component indicates in which bucket the key is supposed to be stored and whose third component is
* an error flag indicating that the bucket could not be found (e.g. due to the restriction that the storage
* must not be increased).
*/
template<bool increaseStorage>
std::tuple<bool, std::size_t, bool> findBucketToInsert(storm::storage::BitVector const& key);
/*!
* Inserts the given key-value pair without resizing the underlying storage. If that fails, this is
* indicated by the return value.
*
* @param key The key to insert.
* @param value The value to insert.
* @return True iff the key-value pair could be inserted without resizing the storage.
*/
bool insertWithoutIncreasingSize(storm::storage::BitVector const& key, ValueType const& value);
/*!
* Increases the size of the hash map and performs the necessary rehashing of all entries.
*/
void increaseSize();
// The load factor determining when the size of the map is increased.
double loadFactor;
// The size of one bucket.
uint64_t bucketSize;
// The number of buckets.
std::size_t numberOfBuckets;
// The buckets that hold the elements of the map.
storm::storage::BitVector buckets;
// A bit vector that stores which buckets actually hold a value.
storm::storage::BitVector occupied;
// A vector of the mapped-to values. The entry at position i is the "target" of the key in bucket i.
std::vector<ValueType> values;
// The number of elements in this map.
std::size_t numberOfElements;
// An iterator to a value in the static sizes table.
std::vector<std::size_t>::const_iterator currentSizeIterator;
// Functor object that are used to perform the actual hashing.
Hash1 hasher1;
Hash2 hasher2;
// A static table that produces the next possible size of the hash table.
static const std::vector<std::size_t> sizes;
};
}
}
#endif /* STORM_STORAGE_BITVECTORHASHMAP_H_ */