parallel_map.h 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #pragma once
  17. #include "parallel_sort.h"
  18. namespace embree
  19. {
  20. /*! implementation of a key/value map with parallel construction */
  21. template<typename Key, typename Val>
  22. class parallel_map
  23. {
  24. /* key/value pair to build the map */
  25. struct KeyValue
  26. {
  27. __forceinline KeyValue () {}
  28. __forceinline KeyValue (const Key key, const Val val)
  29. : key(key), val(val) {}
  30. __forceinline operator Key() const {
  31. return key;
  32. }
  33. public:
  34. Key key;
  35. Val val;
  36. };
  37. public:
  38. /*! parallel map constructors */
  39. parallel_map () {}
  40. /*! construction from pair of vectors */
  41. template<typename KeyVector, typename ValVector>
  42. parallel_map (const KeyVector& keys, const ValVector& values) { init(keys,values); }
  43. /*! initialized the parallel map from a vector with keys and values */
  44. template<typename KeyVector, typename ValVector>
  45. void init(const KeyVector& keys, const ValVector& values)
  46. {
  47. /* reserve sufficient space for all data */
  48. assert(keys.size() == values.size());
  49. vec.resize(keys.size());
  50. /* generate key/value pairs */
  51. parallel_for( size_t(0), keys.size(), size_t(4*4096), [&](const range<size_t>& r) {
  52. for (size_t i=r.begin(); i<r.end(); i++)
  53. vec[i] = KeyValue((Key)keys[i],values[i]);
  54. });
  55. /* perform parallel radix sort of the key/value pairs */
  56. std::vector<KeyValue> temp(keys.size());
  57. radix_sort<KeyValue,Key>(vec.data(),temp.data(),keys.size());
  58. }
  59. /*! Returns a pointer to the value associated with the specified key. The pointer will be nullptr of the key is not contained in the map. */
  60. __forceinline const Val* lookup(const Key& key) const
  61. {
  62. typename std::vector<KeyValue>::const_iterator i = std::lower_bound(vec.begin(), vec.end(), key);
  63. if (i == vec.end()) return nullptr;
  64. if (i->key != key) return nullptr;
  65. return &i->val;
  66. }
  67. /*! If the key is in the map, the function returns the value associated with the key, otherwise it returns the default value. */
  68. __forceinline Val lookup(const Key& key, const Val& def) const
  69. {
  70. typename std::vector<KeyValue>::const_iterator i = std::lower_bound(vec.begin(), vec.end(), key);
  71. if (i == vec.end()) return def;
  72. if (i->key != key) return def;
  73. return i->val;
  74. }
  75. /*! clears all state */
  76. void clear() {
  77. vec.clear();
  78. }
  79. private:
  80. std::vector<KeyValue> vec; //!< vector containing sorted elements
  81. };
  82. }