Skip to content

Commit

Permalink
Add transparent 'bucket' to HashTable and unordered_map (#5072)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marshall Clow authored and GitHub Enterprise committed Nov 11, 2024
1 parent 4e56942 commit ef07cc3
Show file tree
Hide file tree
Showing 14 changed files with 340 additions and 13 deletions.
27 changes: 27 additions & 0 deletions groups/bsl/bslstl/bslstl_hashtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -2552,6 +2552,33 @@ class HashTable {
/// having the specified `key`.
SizeType bucketIndexForKey(const KeyType& key) const;

/// Return the index of the bucket that would contain all the elements
/// equivalent to the specified `key`.
template <class LOOKUP_KEY>
typename bsl::enable_if<
BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
&& BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
SizeType>::type
bucketIndexForKey(const LOOKUP_KEY& key) const
{
typedef typename
HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::SizeType
SizeType;

// The following cast will not discard any useful bits, unless
// 'SizeType' is larger than 'size_t', as the bucket computation takes
// a mod on the supplied number of buckets. We use the following
// 'BSLMF_ASSERT' to assert that assumption at compile time.

BSLMF_ASSERT(sizeof(SizeType) <= sizeof(size_t));

size_t hashCode = this->d_parameters.hashCodeForKey(key);
return static_cast<SizeType>(
bslalg::HashTableImpUtil::computeBucketIndex(
hashCode,
d_anchor.bucketArraySize()));
}

/// Return a reference providing non-modifiable access to the
/// key-equality comparison functor used by this hash table.
const COMPARATOR& comparator() const;
Expand Down
29 changes: 28 additions & 1 deletion groups/bsl/bslstl/bslstl_hashtable_cpp03.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// regions of C++11 code, then this header contains no code and is not
// '#include'd in the original header.
//
// Generated on Sun Sep 1 05:39:09 2024
// Generated on Tue Nov 5 07:45:21 2024
// Command line: sim_cpp11_features.pl bslstl_hashtable.h

#ifdef COMPILING_BSLSTL_HASHTABLE_H
Expand Down Expand Up @@ -2822,6 +2822,33 @@ class HashTable {
/// having the specified `key`.
SizeType bucketIndexForKey(const KeyType& key) const;

/// Return the index of the bucket that would contain all the elements
/// equivalent to the specified `key`.
template <class LOOKUP_KEY>
typename bsl::enable_if<
BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
&& BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
SizeType>::type
bucketIndexForKey(const LOOKUP_KEY& key) const
{
typedef typename
HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::SizeType
SizeType;

// The following cast will not discard any useful bits, unless
// 'SizeType' is larger than 'size_t', as the bucket computation takes
// a mod on the supplied number of buckets. We use the following
// 'BSLMF_ASSERT' to assert that assumption at compile time.

BSLMF_ASSERT(sizeof(SizeType) <= sizeof(size_t));

size_t hashCode = this->d_parameters.hashCodeForKey(key);
return static_cast<SizeType>(
bslalg::HashTableImpUtil::computeBucketIndex(
hashCode,
d_anchor.bucketArraySize()));
}

/// Return a reference providing non-modifiable access to the
/// key-equality comparison functor used by this hash table.
const COMPARATOR& comparator() const;
Expand Down
15 changes: 15 additions & 0 deletions groups/bsl/bslstl/bslstl_unorderedmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -1963,6 +1963,21 @@ class unordered_map {
/// specified `key` would be inserted.
size_type bucket(const key_type& key) const;

/// Return the index of the bucket, in the array of buckets maintained
/// by this unordered map, where values having a key equivalent to the
/// specified `key` would be inserted.
///
/// Note: implemented inline due to Sun CC compilation error.
template <class LOOKUP_KEY>
typename enable_if<
BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
&& BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value,
size_type>::type
bucket(const LOOKUP_KEY& key) const
{
return d_impl.bucketIndexForKey(key);
}

/// Return the number of buckets in the array of buckets maintained by
/// this unordered map.
size_type bucket_count() const BSLS_KEYWORD_NOEXCEPT;
Expand Down
17 changes: 16 additions & 1 deletion groups/bsl/bslstl/bslstl_unorderedmap_cpp03.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// regions of C++11 code, then this header contains no code and is not
// '#include'd in the original header.
//
// Generated on Sun Sep 1 18:48:19 2024
// Generated on Tue Nov 5 08:09:52 2024
// Command line: sim_cpp11_features.pl bslstl_unorderedmap.h

#ifdef COMPILING_BSLSTL_UNORDEREDMAP_H
Expand Down Expand Up @@ -2661,6 +2661,21 @@ class unordered_map {
/// specified `key` would be inserted.
size_type bucket(const key_type& key) const;

/// Return the index of the bucket, in the array of buckets maintained
/// by this unordered map, where values having a key equivalent to the
/// specified `key` would be inserted.
///
/// Note: implemented inline due to Sun CC compilation error.
template <class LOOKUP_KEY>
typename enable_if<
BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
&& BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value,
size_type>::type
bucket(const LOOKUP_KEY& key) const
{
return d_impl.bucketIndexForKey(key);
}

/// Return the number of buckets in the array of buckets maintained by
/// this unordered map.
size_type bucket_count() const BSLS_KEYWORD_NOEXCEPT;
Expand Down
43 changes: 41 additions & 2 deletions groups/bsl/bslstl/bslstl_unorderedmap_test.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1584,8 +1584,9 @@ void testTransparentComparator(Container& container,
bool isTransparent,
int initKeyValue)
{
typedef typename Container::const_iterator Iterator;
typedef typename Container::size_type Count;
typedef typename Container::const_local_iterator LocalIterator;
typedef typename Container::const_iterator Iterator;
typedef typename Container::size_type Count;

int expectedConversionCount = 0;

Expand Down Expand Up @@ -1660,6 +1661,43 @@ void testTransparentComparator(Container& container,
container.equal_range(nonExistingKey);
ASSERT(NON_EXISTING_ER.first == NON_EXISTING_ER.second);
ASSERT(expectedConversionCount == nonExistingKey.conversionCount());

// Testing `bucket`.
const Count bucketFound = container.bucket(existingKey);
const Count bucketNotFound = container.bucket(nonExistingKey);

if (!isTransparent) {
++expectedConversionCount;
}

ASSERTV(expectedConversionCount, existingKey.conversionCount(),
expectedConversionCount == existingKey.conversionCount());
ASSERTV(expectedConversionCount, nonExistingKey.conversionCount(),
expectedConversionCount == nonExistingKey.conversionCount());

// check that we found the right bucket
bool found_it;
const typename Container::key_equal c_eq = container.key_eq();

found_it = false;
for (LocalIterator it = container.begin(bucketFound);
it != container.end(bucketFound);
++it) {
if (c_eq(it->first, existingKey)) {
found_it = true;
}
}
ASSERT(found_it);

found_it = false;
for (LocalIterator it = container.begin(bucketNotFound);
it != container.end(bucketNotFound);
++it) {
if (c_eq(it->first, nonExistingKey)) {
found_it = true;
}
}
ASSERT(!found_it);
}

// ================
Expand Down Expand Up @@ -9794,6 +9832,7 @@ int main(int argc, char *argv[])
// CONCERN: `find` properly handles transparent comparators.
// CONCERN: `count` properly handles transparent comparators.
// CONCERN: `equal_range` properly handles transparent comparators.
// CONCERN: `bucket` properly handles transparent comparators.
// --------------------------------------------------------------------

if (verbose) printf("\n" "TESTING TRANSPARENT COMPARATOR" "\n"
Expand Down
15 changes: 15 additions & 0 deletions groups/bsl/bslstl/bslstl_unorderedmultimap.h
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,21 @@ class unordered_multimap {
/// `key` would be inserted.
size_type bucket(const key_type& key) const;

/// Return the index of the bucket, in the array of buckets maintained
/// by this unordered map, where values having a key equivalent to the
/// specified `key` would be inserted.
///
/// Note: implemented inline due to Sun CC compilation error.
template <class LOOKUP_KEY>
typename enable_if<
BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
&& BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value,
size_type>::type
bucket(const LOOKUP_KEY& key) const
{
return d_impl.bucketIndexForKey(key);
}

/// Return the number of buckets in the array of buckets maintained by
/// this unordered multimap.
size_type bucket_count() const BSLS_KEYWORD_NOEXCEPT;
Expand Down
17 changes: 16 additions & 1 deletion groups/bsl/bslstl/bslstl_unorderedmultimap_cpp03.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// regions of C++11 code, then this header contains no code and is not
// '#include'd in the original header.
//
// Generated on Mon Oct 14 10:32:16 2024
// Generated on Thu Nov 7 07:41:40 2024
// Command line: sim_cpp11_features.pl bslstl_unorderedmultimap.h

#ifdef COMPILING_BSLSTL_UNORDEREDMULTIMAP_H
Expand Down Expand Up @@ -898,6 +898,21 @@ class unordered_multimap {
/// `key` would be inserted.
size_type bucket(const key_type& key) const;

/// Return the index of the bucket, in the array of buckets maintained
/// by this unordered map, where values having a key equivalent to the
/// specified `key` would be inserted.
///
/// Note: implemented inline due to Sun CC compilation error.
template <class LOOKUP_KEY>
typename enable_if<
BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
&& BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value,
size_type>::type
bucket(const LOOKUP_KEY& key) const
{
return d_impl.bucketIndexForKey(key);
}

/// Return the number of buckets in the array of buckets maintained by
/// this unordered multimap.
size_type bucket_count() const BSLS_KEYWORD_NOEXCEPT;
Expand Down
42 changes: 40 additions & 2 deletions groups/bsl/bslstl/bslstl_unorderedmultimap_test.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1361,8 +1361,9 @@ void testTransparentComparator(Container& container,
bool isTransparent,
int initKeyValue)
{
typedef typename Container::const_iterator Iterator;
typedef typename Container::size_type Count;
typedef typename Container::const_local_iterator LocalIterator;
typedef typename Container::const_iterator Iterator;
typedef typename Container::size_type Count;

int expectedConversionCount = 0;

Expand Down Expand Up @@ -1437,6 +1438,43 @@ void testTransparentComparator(Container& container,
container.equal_range(nonExistingKey);
ASSERT(NON_EXISTING_ER.first == NON_EXISTING_ER.second);
ASSERT(expectedConversionCount == nonExistingKey.conversionCount());

// Testing `bucket`.
const Count bucketFound = container.bucket(existingKey);
const Count bucketNotFound = container.bucket(nonExistingKey);

if (!isTransparent) {
++expectedConversionCount;
}

ASSERTV(expectedConversionCount, existingKey.conversionCount(),
expectedConversionCount == existingKey.conversionCount());
ASSERTV(expectedConversionCount, nonExistingKey.conversionCount(),
expectedConversionCount == nonExistingKey.conversionCount());

// check that we found the right bucket
bool found_it;
const typename Container::key_equal c_eq = container.key_eq();

found_it = false;
for (LocalIterator it = container.begin(bucketFound);
it != container.end(bucketFound);
++it) {
if (c_eq(it->first, existingKey)) {
found_it = true;
}
}
ASSERT(found_it);

found_it = false;
for (LocalIterator it = container.begin(bucketNotFound);
it != container.end(bucketNotFound);
++it) {
if (c_eq(it->first, nonExistingKey)) {
found_it = true;
}
}
ASSERT(!found_it);
}

} // close unnamed namespace
Expand Down
15 changes: 15 additions & 0 deletions groups/bsl/bslstl/bslstl_unorderedmultiset.h
Original file line number Diff line number Diff line change
Expand Up @@ -1489,6 +1489,21 @@ class unordered_multiset
/// inserted.
size_type bucket(const key_type& key) const;

/// Return the index of the bucket, in the array of buckets of this
/// container, where a value equivalent to the specified `key` would be
/// inserted.
///
/// Note: implemented inline due to Sun CC compilation error.
template <class LOOKUP_KEY>
typename enable_if<
BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
&& BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value,
size_type>::type
bucket(const LOOKUP_KEY& key) const
{
return d_impl.bucketIndexForKey(key);
}

/// Return the number of buckets in the array of buckets maintained by
/// this unordered multiset.
size_type bucket_count() const BSLS_KEYWORD_NOEXCEPT;
Expand Down
17 changes: 16 additions & 1 deletion groups/bsl/bslstl/bslstl_unorderedmultiset_cpp03.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// regions of C++11 code, then this header contains no code and is not
// '#include'd in the original header.
//
// Generated on Sun Sep 1 18:48:19 2024
// Generated on Thu Nov 7 07:41:40 2024
// Command line: sim_cpp11_features.pl bslstl_unorderedmultiset.h

#ifdef COMPILING_BSLSTL_UNORDEREDMULTISET_H
Expand Down Expand Up @@ -1111,6 +1111,21 @@ class unordered_multiset
/// inserted.
size_type bucket(const key_type& key) const;

/// Return the index of the bucket, in the array of buckets of this
/// container, where a value equivalent to the specified `key` would be
/// inserted.
///
/// Note: implemented inline due to Sun CC compilation error.
template <class LOOKUP_KEY>
typename enable_if<
BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
&& BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value,
size_type>::type
bucket(const LOOKUP_KEY& key) const
{
return d_impl.bucketIndexForKey(key);
}

/// Return the number of buckets in the array of buckets maintained by
/// this unordered multiset.
size_type bucket_count() const BSLS_KEYWORD_NOEXCEPT;
Expand Down
Loading

0 comments on commit ef07cc3

Please sign in to comment.