// -*- C++ -*- // Copyright (C) 2005-2021 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, or (at your option) any later // version. // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // You should have received a copy of the GNU General Public License // along with this library; see the file COPYING3. If not see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_shift_mask_example.cpp * An example showing how to write a range-hasing functor. */ /** * In some rare cases, advance knowledge of the distribution of keys allows * writing more efficient hash-related policies. * In the rather simplistic case of the example, it is known in advance that * all keys have 0 two lowest bits. The example shows how to write * a range-hashing function disregarding the two lowest bits of the hash value. */ #include #include #include using namespace std; using namespace __gnu_pbds; // A simple hash functor. hash could serve instead of this functor, // but it is not yet standard everywhere. struct simple_int_hash { size_t operator()(int i) const { return i; } }; // A range-hashing function which shifts 2 bits right and then masks. class shift_two_mask_range_hashing : private direct_mask_range_hashing<> { public: typedef size_t size_type; // Swaps with a different instant. void swap(shift_two_mask_range_hashing& other) { direct_mask_range_hashing<>::swap(other); } // Called by the container when internally resized. void notify_resized(size_type size) { direct_mask_range_hashing<>::notify_resized(size); } // Given a hash value, returns a number in the range of the internal // size of the container. inline size_type operator()(size_type hash) const { return direct_mask_range_hashing<>::operator()(hash >> 2); } }; int main() { // A collision-chaining hash table mapping ints to chars. typedef cc_hash_table< int, char, // Hash function. simple_int_hash, equal_to, // Range hashing function. shift_two_mask_range_hashing> map_t; map_t h; // Use normally. h[16] = 'a'; h[256] = 'e'; h[4] = 'z'; return 0; }