summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorGeir Storli <geirstorli@yahoo.no>2016-12-16 11:05:08 +0100
committerGitHub <noreply@github.com>2016-12-16 11:05:08 +0100
commited2ade0445a1124195762234957b7af362079a6b (patch)
tree095c651acaabc2e8f27e3b5006311634cb4e6703 /vespalib
parentfb3dfdeb2383dfac33ba56c80590ed8b84701a99 (diff)
parent2baf2f8195b1a3224ed7989eff1d85a1e64ba46c (diff)
Merge pull request #1336 from yahoo/balder/split-in-hpp-rebased-1
Balder/split in hpp rebased 1
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/tests/array/array_test.cpp7
-rw-r--r--vespalib/src/tests/stllike/hash_test.cpp10
-rw-r--r--vespalib/src/tests/stllike/hashtable_test.cpp7
-rw-r--r--vespalib/src/tests/stllike/lookup_benchmark.cpp2
-rw-r--r--vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/data/memorydatastore.cpp1
-rw-r--r--vespalib/src/vespa/vespalib/data/memorydatastore.h1
-rw-r--r--vespalib/src/vespa/vespalib/data/slime/binary_format.cpp1
-rw-r--r--vespalib/src/vespa/vespalib/data/slime/symbol_table.cpp21
-rw-r--r--vespalib/src/vespa/vespalib/data/slime/symbol_table.h23
-rw-r--r--vespalib/src/vespa/vespalib/eval/llvm/llvm_wrapper.cpp1
-rw-r--r--vespalib/src/vespa/vespalib/stllike/CMakeLists.txt3
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_map.cpp23
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_map.h62
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_map.hpp70
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_map_equal.hpp21
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_map_insert.hpp18
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_set.cpp15
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_set.h57
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_set.hpp88
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_set_insert.hpp27
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hashtable.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hashtable.h265
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hashtable.hpp289
-rw-r--r--vespalib/src/vespa/vespalib/tensor/dense/dense_tensor_builder.cpp4
-rw-r--r--vespalib/src/vespa/vespalib/tensor/dense/dense_tensor_cells_iterator.h1
-rw-r--r--vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor.cpp7
-rw-r--r--vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor.h2
-rw-r--r--vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_address_reducer.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_builder.cpp1
-rw-r--r--vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_match.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/tensor/tensor_apply.cpp1
-rw-r--r--vespalib/src/vespa/vespalib/tensor/tensor_mapper.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/tensor/types.h1
-rw-r--r--vespalib/src/vespa/vespalib/util/CMakeLists.txt1
-rw-r--r--vespalib/src/vespa/vespalib/util/array.cpp19
-rw-r--r--vespalib/src/vespa/vespalib/util/array.h251
-rw-r--r--vespalib/src/vespa/vespalib/util/array.hpp196
-rw-r--r--vespalib/src/vespa/vespalib/util/array_equal.hpp25
-rw-r--r--vespalib/src/vespa/vespalib/util/arrayref.h49
-rw-r--r--vespalib/src/vespa/vespalib/util/generationholder.h4
-rw-r--r--vespalib/src/vespa/vespalib/util/stash.h3
42 files changed, 955 insertions, 632 deletions
diff --git a/vespalib/src/tests/array/array_test.cpp b/vespalib/src/tests/array/array_test.cpp
index 231bc00611a..fb4a824ec00 100644
--- a/vespalib/src/tests/array/array_test.cpp
+++ b/vespalib/src/tests/array/array_test.cpp
@@ -1,13 +1,10 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/fastos/fastos.h>
-#include <vespa/log/log.h>
-#include <vespa/vespalib/util/array.h>
+
+#include <vespa/vespalib/util/array.hpp>
#include <vespa/vespalib/stllike/string.h>
#include <vespa/vespalib/testkit/testapp.h>
#include <deque>
-LOG_SETUP("array_test");
-
using namespace vespalib;
class Test : public TestApp
diff --git a/vespalib/src/tests/stllike/hash_test.cpp b/vespalib/src/tests/stllike/hash_test.cpp
index cae98bf0e40..e88e608b94b 100644
--- a/vespalib/src/tests/stllike/hash_test.cpp
+++ b/vespalib/src/tests/stllike/hash_test.cpp
@@ -1,10 +1,10 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/fastos/fastos.h>
-#include <vespa/log/log.h>
-LOG_SETUP("hash_test");
+
#include <vespa/vespalib/testkit/testapp.h>
-#include <vespa/vespalib/stllike/hash_set.h>
-#include <vespa/vespalib/stllike/hash_map.h>
+#include <vespa/vespalib/stllike/hash_set.hpp>
+#include <vespa/vespalib/stllike/hash_map.hpp>
+#include <vespa/vespalib/stllike/hash_map_equal.hpp>
+#include <cstddef>
using namespace vespalib;
using std::make_pair;
diff --git a/vespalib/src/tests/stllike/hashtable_test.cpp b/vespalib/src/tests/stllike/hashtable_test.cpp
index 7516ca1ab34..67cf953aac0 100644
--- a/vespalib/src/tests/stllike/hashtable_test.cpp
+++ b/vespalib/src/tests/stllike/hashtable_test.cpp
@@ -1,11 +1,8 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// Unit tests for hashtable.
-#include <vespa/log/log.h>
-LOG_SETUP("hashtable_test");
-#include <vespa/fastos/fastos.h>
-
-#include <vespa/vespalib/stllike/hashtable.h>
+#include <vespa/vespalib/stllike/hashtable.hpp>
+#include <vespa/vespalib/stllike/hash_fun.h>
#include <vespa/vespalib/testkit/testapp.h>
#include <memory>
#include <vector>
diff --git a/vespalib/src/tests/stllike/lookup_benchmark.cpp b/vespalib/src/tests/stllike/lookup_benchmark.cpp
index 0a82bfa292b..9358f189f0a 100644
--- a/vespalib/src/tests/stllike/lookup_benchmark.cpp
+++ b/vespalib/src/tests/stllike/lookup_benchmark.cpp
@@ -8,7 +8,7 @@
#include <tr1/unordered_set>
#include <vector>
#include <algorithm>
-#include <vespa/vespalib/stllike/hash_set.h>
+#include <vespa/vespalib/stllike/hash_set.hpp>
template <typename S>
void fill(S & s, size_t count)
diff --git a/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp b/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp
index 04c3faf362a..5497017947e 100644
--- a/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp
+++ b/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp
@@ -8,7 +8,7 @@
#include <tr1/unordered_set>
#include <vector>
#include <algorithm>
-#include <vespa/vespalib/stllike/hash_set.h>
+#include <vespa/vespalib/stllike/hash_set.hpp>
template <typename T>
class RoundRobinAllocator
diff --git a/vespalib/src/vespa/vespalib/data/memorydatastore.cpp b/vespalib/src/vespa/vespalib/data/memorydatastore.cpp
index 824a8adf1d6..73b0d559a15 100644
--- a/vespalib/src/vespa/vespalib/data/memorydatastore.cpp
+++ b/vespalib/src/vespa/vespalib/data/memorydatastore.cpp
@@ -1,5 +1,6 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/data/memorydatastore.h>
+#include <vespa/vespalib/util/array.hpp>
namespace vespalib {
diff --git a/vespalib/src/vespa/vespalib/data/memorydatastore.h b/vespalib/src/vespa/vespalib/data/memorydatastore.h
index dd5809c1423..58aa4981d29 100644
--- a/vespalib/src/vespa/vespalib/data/memorydatastore.h
+++ b/vespalib/src/vespa/vespalib/data/memorydatastore.h
@@ -4,6 +4,7 @@
#include <vespa/vespalib/util/alloc.h>
#include <vespa/vespalib/util/array.h>
#include <vespa/vespalib/util/sync.h>
+#include <vector>
namespace vespalib {
diff --git a/vespalib/src/vespa/vespalib/data/slime/binary_format.cpp b/vespalib/src/vespa/vespalib/data/slime/binary_format.cpp
index d3026211c61..be2089b4076 100644
--- a/vespalib/src/vespa/vespalib/data/slime/binary_format.cpp
+++ b/vespalib/src/vespa/vespalib/data/slime/binary_format.cpp
@@ -3,6 +3,7 @@
#include "binary_format.h"
#include "inserter.h"
#include "slime.h"
+#include <vespa/vespalib/util/array.hpp>
namespace vespalib {
namespace slime {
diff --git a/vespalib/src/vespa/vespalib/data/slime/symbol_table.cpp b/vespalib/src/vespa/vespalib/data/slime/symbol_table.cpp
index 57b0b2e843a..fe1d0a1a78b 100644
--- a/vespalib/src/vespa/vespalib/data/slime/symbol_table.cpp
+++ b/vespalib/src/vespa/vespalib/data/slime/symbol_table.cpp
@@ -1,6 +1,7 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "symbol_table.h"
+#include <vespa/vespalib/stllike/hash_map.hpp>
namespace vespalib {
namespace slime {
@@ -18,5 +19,25 @@ SymbolTable::clear() {
_symbols.clear();
}
+Symbol
+SymbolTable::insert(const Memory &name) {
+ SymbolMap::const_iterator pos = _symbols.find(name);
+ if (pos == _symbols.end()) {
+ Symbol symbol(_names.size());
+ SymbolVector::Reference r(_names.push_back(name.data, name.size));
+ _symbols.insert(std::make_pair(Memory(r.c_str(), r.size()), symbol));
+ return symbol;
+ }
+ return pos->second;
+}
+Symbol
+SymbolTable::lookup(const Memory &name) const {
+ SymbolMap::const_iterator pos = _symbols.find(name);
+ if (pos == _symbols.end()) {
+ return Symbol();
+ }
+ return pos->second;
+}
+
} // namespace vespalib::slime
} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/data/slime/symbol_table.h b/vespalib/src/vespa/vespalib/data/slime/symbol_table.h
index 23cdbecdb5e..e4cafa2b9d6 100644
--- a/vespalib/src/vespa/vespalib/data/slime/symbol_table.h
+++ b/vespalib/src/vespa/vespalib/data/slime/symbol_table.h
@@ -21,8 +21,8 @@ private:
return lcm.hash();
}
};
- typedef hash_map<Memory, Symbol, hasher> SymbolMap;
- typedef VariableSizeVector SymbolVector;
+ using SymbolMap = hash_map<Memory, Symbol, hasher>;
+ using SymbolVector = VariableSizeVector;
SymbolMap _symbols;
SymbolVector _names;
@@ -38,23 +38,8 @@ public:
SymbolVector::Reference r(_names[symbol.getValue()]);
return Memory(r.c_str(), r.size());
}
- Symbol insert(const Memory &name) {
- SymbolMap::const_iterator pos = _symbols.find(name);
- if (pos == _symbols.end()) {
- Symbol symbol(_names.size());
- SymbolVector::Reference r(_names.push_back(name.data, name.size));
- _symbols.insert(std::make_pair(Memory(r.c_str(), r.size()), symbol));
- return symbol;
- }
- return pos->second;
- }
- Symbol lookup(const Memory &name) const {
- SymbolMap::const_iterator pos = _symbols.find(name);
- if (pos == _symbols.end()) {
- return Symbol();
- }
- return pos->second;
- }
+ Symbol insert(const Memory &name);
+ Symbol lookup(const Memory &name) const;
void clear();
};
diff --git a/vespalib/src/vespa/vespalib/eval/llvm/llvm_wrapper.cpp b/vespalib/src/vespa/vespalib/eval/llvm/llvm_wrapper.cpp
index c5ceacb3a5a..1222eeae837 100644
--- a/vespalib/src/vespa/vespalib/eval/llvm/llvm_wrapper.cpp
+++ b/vespalib/src/vespa/vespalib/eval/llvm/llvm_wrapper.cpp
@@ -1,6 +1,5 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/fastos/fastos.h>
#include <cmath>
#include "llvm_wrapper.h"
#include <vespa/vespalib/eval/node_visitor.h>
diff --git a/vespalib/src/vespa/vespalib/stllike/CMakeLists.txt b/vespalib/src/vespa/vespalib/stllike/CMakeLists.txt
index c03dc4d1703..3900c6210d4 100644
--- a/vespalib/src/vespa/vespalib/stllike/CMakeLists.txt
+++ b/vespalib/src/vespa/vespalib/stllike/CMakeLists.txt
@@ -3,6 +3,9 @@ vespa_add_library(vespalib_vespalib_stllike OBJECT
SOURCES
asciistream.cpp
hashtable.cpp
+ hashtable.cpp
+ hash_set.cpp
+ hash_map.cpp
string.cpp
DEPENDS
)
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_map.cpp b/vespalib/src/vespa/vespalib/stllike/hash_map.cpp
new file mode 100644
index 00000000000..4b51bfdb1f7
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/stllike/hash_map.cpp
@@ -0,0 +1,23 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "hash_map.hpp"
+#include "hash_map_equal.hpp"
+#include <vespa/vespalib/util/array_equal.hpp>
+
+namespace vespalib {
+}
+
+VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, vespalib::string);
+VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, int32_t);
+VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, uint32_t);
+VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, uint64_t);
+VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, double);
+VESPALIB_HASH_MAP_INSTANTIATE(int64_t, int32_t);
+VESPALIB_HASH_MAP_INSTANTIATE(int64_t, uint32_t);
+VESPALIB_HASH_MAP_INSTANTIATE(int32_t, uint32_t);
+VESPALIB_HASH_MAP_INSTANTIATE(uint32_t, int32_t);
+VESPALIB_HASH_MAP_INSTANTIATE(uint32_t, uint32_t);
+VESPALIB_HASH_MAP_INSTANTIATE(uint64_t, uint32_t);
+VESPALIB_HASH_MAP_INSTANTIATE(uint64_t, uint64_t);
+VESPALIB_HASH_MAP_INSTANTIATE(double, uint32_t);
+VESPALIB_HASH_MAP_INSTANTIATE(float, uint32_t);
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_map.h b/vespalib/src/vespa/vespalib/stllike/hash_map.h
index 22f352fcd99..51a8151e91a 100644
--- a/vespalib/src/vespa/vespalib/stllike/hash_map.h
+++ b/vespalib/src/vespa/vespalib/stllike/hash_map.h
@@ -1,7 +1,8 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
-#include <vespa/vespalib/stllike/hashtable.h>
+#include "hashtable.h"
+#include "hash_fun.h"
namespace vespalib {
@@ -12,15 +13,20 @@ public:
typedef std::pair<K, V> value_type;
typedef K key_type;
typedef V mapped_type;
+ using HashTable = hashtable< K, value_type, H, EQ, std::_Select1st< value_type >, M >;
private:
- typedef hashtable< K, value_type, H, EQ, std::_Select1st< value_type >, M > HashTable;
HashTable _ht;
public:
typedef typename HashTable::iterator iterator;
typedef typename HashTable::const_iterator const_iterator;
typedef typename HashTable::insert_result insert_result;
public:
- hash_map(size_t reserveSize=0) : _ht(reserveSize) { }
+ hash_map(hash_map &&) = default;
+ hash_map & operator = (hash_map &&) = default;
+ hash_map(const hash_map &) = default;
+ hash_map & operator = (const hash_map &) = default;
+ hash_map(size_t reserveSize=0);
+ ~hash_map();
iterator begin() { return _ht.begin(); }
iterator end() { return _ht.end(); }
const_iterator begin() const { return _ht.begin(); }
@@ -28,52 +34,28 @@ public:
size_t capacity() const { return _ht.capacity(); }
size_t size() const { return _ht.size(); }
bool empty() const { return _ht.empty(); }
- insert_result insert(const value_type & value) { return _ht.insert(value); }
+ insert_result insert(const value_type & value);
template <typename InputIt>
void insert(InputIt first, InputIt last);
- const V & operator [] (const K & key) const { return _ht.find(key)->second; }
- V & operator [] (const K & key) { return _ht.insert(value_type(key, V())).first->second; }
- void erase(const K & key) { return _ht.erase(key); }
- void erase(iterator it) { return _ht.erase(it->first); }
- void erase(const_iterator it) { return _ht.erase(it->first); }
- iterator find(const K & key) { return _ht.find(key); }
- const_iterator find(const K & key) const { return _ht.find(key); }
- void clear() { _ht.clear(); }
- void resize(size_t newSize) { _ht.resize(newSize); }
- void swap(hash_map & rhs) { _ht.swap(rhs._ht); }
+ const V & operator [] (const K & key) const { return _ht.find(key)->second; }
+ V & operator [] (const K & key) { return _ht.insert(value_type(key, V())).first->second; }
+ void erase(const K & key);
+ void erase(iterator it) { return erase(it->first); }
+ void erase(const_iterator it) { return erase(it->first); }
+ iterator find(const K & key) { return _ht.find(key); }
+ const_iterator find(const K & key) const { return _ht.find(key); }
+ void clear();
+ void resize(size_t newSize);
+ void swap(hash_map & rhs);
bool operator == (const hash_map & rhs) const;
- size_t getMemoryConsumption() const { return _ht.getMemoryConsumption(); }
- size_t getMemoryUsed() const { return _ht.getMemoryUsed(); }
+ size_t getMemoryConsumption() const;
+ size_t getMemoryUsed() const;
};
-template <typename K, typename V, typename H, typename EQ, typename M>
-bool hash_map<K, V, H, EQ, M>::operator ==(const hash_map & rhs) const {
- bool identical(rhs.size() == size());
- if (identical) {
- for(const_iterator at(begin()), mat(end()); identical && at != mat; at++) {
- const_iterator bt = rhs.find(at->first);
- identical = (bt != rhs.end()) && (*at == *bt);
- }
- }
- return identical;
-}
-
-template <typename K, typename V, typename H, typename EQ, typename M>
-template <typename InputIt>
-void hash_map<K, V, H, EQ, M>::insert(InputIt first, InputIt last) {
- while (first != last) {
- _ht.insert(*first);
- ++first;
- }
-}
-
template< typename K, typename V, typename H, typename EQ, typename M >
void swap(hash_map<K, V, H, EQ, M> & a, hash_map<K, V, H, EQ, M> & b)
{
a.swap(b);
}
-
}
-
-
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_map.hpp b/vespalib/src/vespa/vespalib/stllike/hash_map.hpp
new file mode 100644
index 00000000000..74d39e58c6b
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/stllike/hash_map.hpp
@@ -0,0 +1,70 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include "hash_map_insert.hpp"
+#include "hashtable.hpp"
+
+namespace vespalib {
+
+template <typename K, typename V, typename H, typename EQ, typename M>
+hash_map<K, V, H, EQ, M>::hash_map(size_t reserveSize) :
+ _ht(reserveSize)
+{ }
+
+template <typename K, typename V, typename H, typename EQ, typename M>
+hash_map<K, V, H, EQ, M>::~hash_map() { }
+
+template <typename K, typename V, typename H, typename EQ, typename M>
+typename hash_map<K, V, H, EQ, M>::insert_result
+hash_map<K, V, H, EQ, M>::insert(const value_type & value) {
+ return _ht.insert(value);
+}
+
+template <typename K, typename V, typename H, typename EQ, typename M>
+void
+hash_map<K, V, H, EQ, M>::erase(const K & key) {
+ return _ht.erase(key);
+}
+
+template <typename K, typename V, typename H, typename EQ, typename M>
+void
+hash_map<K, V, H, EQ, M>::clear() {
+ _ht.clear();
+}
+
+template <typename K, typename V, typename H, typename EQ, typename M>
+void
+hash_map<K, V, H, EQ, M>::resize(size_t newSize) {
+ _ht.resize(newSize);
+}
+
+template <typename K, typename V, typename H, typename EQ, typename M>
+void
+hash_map<K, V, H, EQ, M>::swap(hash_map & rhs) {
+ _ht.swap(rhs._ht);
+}
+
+template <typename K, typename V, typename H, typename EQ, typename M>
+size_t
+hash_map<K, V, H, EQ, M>::getMemoryConsumption() const {
+ return _ht.getMemoryConsumption();
+}
+
+template <typename K, typename V, typename H, typename EQ, typename M>
+size_t
+hash_map<K, V, H, EQ, M>::getMemoryUsed() const
+{
+ return _ht.getMemoryUsed();
+}
+
+}
+
+#define VESPALIB_HASH_MAP_INSTANTIATE_H(K, V, H) \
+ template class vespalib::hash_map<K, V, H>; \
+ template class vespalib::hashtable<K, std::pair<K,V>, H, std::equal_to<K>, std::_Select1st<std::pair<K,V>>>; \
+ template vespalib::hashtable<K, std::pair<K,V>, H, std::equal_to<K>, std::_Select1st<std::pair<K,V>>>::insert_result \
+ vespalib::hashtable<K, std::pair<K,V>, H, std::equal_to<K>, std::_Select1st<std::pair<K,V>>>::insert(std::pair<K,V> &&); \
+ template class vespalib::Array<vespalib::hash_node<std::pair<K,V>>>;
+
+#define VESPALIB_HASH_MAP_INSTANTIATE(K, V) VESPALIB_HASH_MAP_INSTANTIATE_H(K, V, vespalib::hash<K>)
+
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_map_equal.hpp b/vespalib/src/vespa/vespalib/stllike/hash_map_equal.hpp
new file mode 100644
index 00000000000..b7b40b1307a
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/stllike/hash_map_equal.hpp
@@ -0,0 +1,21 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include "hash_map.h"
+
+namespace vespalib {
+
+template <typename K, typename V, typename H, typename EQ, typename M>
+bool
+hash_map<K, V, H, EQ, M>::operator ==(const hash_map & rhs) const {
+ bool identical(rhs.size() == size());
+ if (identical) {
+ for(const_iterator at(begin()), mat(end()); identical && at != mat; at++) {
+ const_iterator bt = rhs.find(at->first);
+ identical = (bt != rhs.end()) && (*at == *bt);
+ }
+ }
+ return identical;
+}
+
+}
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_map_insert.hpp b/vespalib/src/vespa/vespalib/stllike/hash_map_insert.hpp
new file mode 100644
index 00000000000..30d07163ce1
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/stllike/hash_map_insert.hpp
@@ -0,0 +1,18 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include "hash_map.h"
+
+namespace vespalib {
+
+template <typename K, typename V, typename H, typename EQ, typename M>
+template <typename InputIt>
+void
+hash_map<K, V, H, EQ, M>::insert(InputIt first, InputIt last) {
+ while (first != last) {
+ insert(*first);
+ ++first;
+ }
+}
+
+}
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_set.cpp b/vespalib/src/vespa/vespalib/stllike/hash_set.cpp
new file mode 100644
index 00000000000..506e17828c4
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/stllike/hash_set.cpp
@@ -0,0 +1,15 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "hash_set.hpp"
+#include <vespa/vespalib/util/array_equal.hpp>
+
+namespace vespalib {
+}
+
+VESPALIB_HASH_SET_INSTANTIATE(int32_t);
+VESPALIB_HASH_SET_INSTANTIATE(uint32_t);
+VESPALIB_HASH_SET_INSTANTIATE(uint64_t);
+VESPALIB_HASH_SET_INSTANTIATE(double);
+VESPALIB_HASH_SET_INSTANTIATE(vespalib::string);
+VESPALIB_HASH_SET_INSTANTIATE(std::string);
+VESPALIB_HASH_SET_INSTANTIATE(const void *);
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_set.h b/vespalib/src/vespa/vespalib/stllike/hash_set.h
index ff7049b7784..c74a377cc18 100644
--- a/vespalib/src/vespa/vespalib/stllike/hash_set.h
+++ b/vespalib/src/vespa/vespalib/stllike/hash_set.h
@@ -1,7 +1,8 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
-#include <vespa/vespalib/stllike/hashtable.h>
+#include "hashtable.h"
+#include "hash_fun.h"
#include <initializer_list>
namespace vespalib {
@@ -10,26 +11,24 @@ template< typename K, typename H = vespalib::hash<K>, typename EQ = std::equal_t
class hash_set
{
private:
- typedef hashtable< K, K, H, EQ, std::_Identity<K>, M> HashTable;
+ using HashTable = hashtable< K, K, H, EQ, std::_Identity<K>, M>;
HashTable _ht;
public:
typedef typename HashTable::iterator iterator;
typedef typename HashTable::const_iterator const_iterator;
typedef typename HashTable::insert_result insert_result;
public:
- hash_set(size_t reserveSize=0) : _ht(reserveSize) { }
- hash_set(size_t reserveSize, const H & hasher, const EQ & equal) : _ht(reserveSize, hasher, equal) { }
+ hash_set(hash_set &&) = default;
+ hash_set & operator = (hash_set &&) = default;
+ hash_set(const hash_set &) = default;
+ hash_set & operator = (const hash_set &) = default;
+ hash_set(size_t reserveSize=0);
+ hash_set(size_t reserveSize, const H & hasher, const EQ & equal);
template <typename InputIterator>
- hash_set(InputIterator first, InputIterator last)
- : _ht(0)
- {
- insert(first, last);
- }
- hash_set(std::initializer_list<K> input)
- : _ht(0)
- {
- insert(input.begin(), input.end());
- }
+ hash_set(InputIterator first, InputIterator last);
+
+ hash_set(std::initializer_list<K> input);
+ ~hash_set();
iterator begin() { return _ht.begin(); }
iterator end() { return _ht.end(); }
const_iterator begin() const { return _ht.begin(); }
@@ -37,16 +36,10 @@ public:
size_t capacity() const { return _ht.capacity(); }
size_t size() const { return _ht.size(); }
bool empty() const { return _ht.empty(); }
- insert_result insert(const K & value) { return _ht.insert(value); }
+ insert_result insert(const K & value);
template<typename InputIt>
- void insert(InputIt first, InputIt last) {
- _ht.resize(last-first + capacity());
- for(;first < last; first++) {
- _ht.insert(*first);
- }
- }
- void erase(const K & key) { return _ht.erase(key); }
- void erase(const iterator & it) { return _ht.erase(it); }
+ void insert(InputIt first, InputIt last);
+ void erase(const K & key);
iterator find(const K & key) { return _ht.find(key); }
const_iterator find(const K & key) const { return _ht.find(key); }
@@ -66,25 +59,17 @@ public:
return _ht.template find<AltKey, AltExtract, AltHash, AltEqual>(key, altExtract);
}
- void clear() { _ht.clear(); }
- void resize(size_t newSize) { _ht.resize(newSize); }
- void swap(hash_set & rhs) { _ht.swap(rhs._ht); }
+ void clear();
+ void resize(size_t newSize);
+ void swap(hash_set & rhs);
- bool operator==(const hash_set &rhs) const {
- bool equal = (size() == rhs.size());
- if (equal) {
- for (auto itr = begin(), endItr = end(); equal && itr != endItr; ++itr) {
- equal = (rhs.find(*itr) != rhs.end());
- }
- }
- return equal;
- }
+ bool operator==(const hash_set &rhs) const;
/**
* Get an approximate number of memory consumed by hash set. Not including
* any data K would store outside of sizeof(K) of course.
*/
- size_t getMemoryConsumption() const { return _ht.getMemoryConsumption(); }
+ size_t getMemoryConsumption() const;
};
template< typename K, typename H, typename EQ, typename M >
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_set.hpp b/vespalib/src/vespa/vespalib/stllike/hash_set.hpp
new file mode 100644
index 00000000000..8be7d982e80
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/stllike/hash_set.hpp
@@ -0,0 +1,88 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include "hash_set_insert.hpp"
+#include "hashtable.hpp"
+
+namespace vespalib {
+
+template<typename K, typename H, typename EQ, typename M>
+hash_set<K, H, EQ, M>::hash_set(size_t reserveSize)
+ : _ht(reserveSize)
+{ }
+
+template<typename K, typename H, typename EQ, typename M>
+hash_set<K, H, EQ, M>::hash_set(size_t reserveSize, const H &hasher, const EQ &equal)
+ : _ht(reserveSize, hasher, equal)
+{ }
+
+template<typename K, typename H, typename EQ, typename M>
+hash_set<K, H, EQ, M>::hash_set(std::initializer_list<K> input)
+ : _ht(0)
+{
+ insert(input.begin(), input.end());
+}
+
+template<typename K, typename H, typename EQ, typename M>
+hash_set<K, H, EQ, M>::~hash_set() {}
+
+template<typename K, typename H, typename EQ, typename M>
+bool
+hash_set<K, H, EQ, M>::operator==(const hash_set &rhs) const {
+ bool equal = (size() == rhs.size());
+ if (equal) {
+ for (auto itr = begin(), endItr = end(); equal && itr != endItr; ++itr) {
+ equal = (rhs.find(*itr) != rhs.end());
+ }
+ }
+ return equal;
+}
+
+template<typename K, typename H, typename EQ, typename M>
+void
+hash_set<K, H, EQ, M>::clear() {
+ _ht.clear();
+}
+
+template<typename K, typename H, typename EQ, typename M>
+void
+hash_set<K, H, EQ, M>::resize(size_t newSize) {
+ _ht.resize(newSize);
+}
+
+template<typename K, typename H, typename EQ, typename M>
+void
+hash_set<K, H, EQ, M>::swap(hash_set &rhs) {
+ _ht.swap(rhs._ht);
+}
+
+template<typename K, typename H, typename EQ, typename M>
+size_t
+hash_set<K, H, EQ, M>::getMemoryConsumption() const {
+ return _ht.getMemoryConsumption();
+}
+
+template<typename K, typename H, typename EQ, typename M>
+void
+hash_set<K, H, EQ, M>::erase(const K &key) {
+ return _ht.erase(key);
+}
+
+template<typename K, typename H, typename EQ, typename M>
+typename hash_set<K, H, EQ, M>::insert_result
+hash_set<K, H, EQ, M>::insert(const K & value) {
+ return _ht.insert(value);
+}
+
+}
+
+#define VESPALIB_HASH_SET_INSTANTIATE(K) \
+ template class vespalib::hash_set<K>; \
+ template class vespalib::hashtable<K, K, vespalib::hash<K>, std::equal_to<K>, std::_Identity<K>>; \
+ template class vespalib::Array<vespalib::hash_node<K>>;
+
+#define VESPALIB_HASH_SET_INSTANTIATE_H(K, H) \
+ template class vespalib::hash_set<K, H>; \
+ template class vespalib::hashtable<K, K, H, std::equal_to<K>, std::_Identity<K>>; \
+ template class vespalib::Array<vespalib::hash_node<K>>;
+
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_set_insert.hpp b/vespalib/src/vespa/vespalib/stllike/hash_set_insert.hpp
new file mode 100644
index 00000000000..a0bd94bafaa
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/stllike/hash_set_insert.hpp
@@ -0,0 +1,27 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include "hash_set.h"
+
+namespace vespalib {
+
+template<typename K, typename H, typename EQ, typename M>
+template<typename InputIterator>
+hash_set<K, H, EQ, M>::hash_set(InputIterator first, InputIterator last)
+ : _ht(0)
+{
+ insert(first, last);
+}
+
+template<typename K, typename H, typename EQ, typename M>
+template<typename InputIt>
+void
+hash_set<K, H, EQ, M>::insert(InputIt first, InputIt last) {
+ _ht.resize(last - first + capacity());
+ for (; first < last; first++) {
+ insert(*first);
+ }
+}
+
+}
diff --git a/vespalib/src/vespa/vespalib/stllike/hashtable.cpp b/vespalib/src/vespa/vespalib/stllike/hashtable.cpp
index e2da6b255af..28423e5263e 100644
--- a/vespalib/src/vespa/vespalib/stllike/hashtable.cpp
+++ b/vespalib/src/vespa/vespalib/stllike/hashtable.cpp
@@ -1,5 +1,5 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/vespalib/stllike/hashtable.h>
+#include <vespa/vespalib/stllike/hashtable.hpp>
namespace {
diff --git a/vespalib/src/vespa/vespalib/stllike/hashtable.h b/vespalib/src/vespa/vespalib/stllike/hashtable.h
index a1eeb289c31..ae30f04d1d1 100644
--- a/vespalib/src/vespa/vespalib/stllike/hashtable.h
+++ b/vespalib/src/vespa/vespalib/stllike/hashtable.h
@@ -1,15 +1,9 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
-#include <vector>
#include <iterator>
-#include <cstddef>
-#include <bits/stl_algo.h>
-#include <bits/stl_function.h>
#include <vespa/vespalib/util/array.h>
-#include "hash_fun.h"
-
namespace vespalib {
/**
@@ -113,6 +107,9 @@ public:
hash_node &operator=(hash_node &&) = default;
hash_node(const hash_node &) = default; // These will not be created
hash_node &operator=(const hash_node &) = default; // if V is non-copyable.
+ bool operator == (const hash_node & rhs) const {
+ return (_next == rhs._next) && (_node == rhs._node);
+ }
V & getValue() { return _node; }
const V & getValue() const { return _node; }
next_t getNext() const { return _next; }
@@ -227,6 +224,10 @@ public:
typedef std::pair<iterator, bool> insert_result;
public:
+ hashtable(hashtable &&) = default;
+ hashtable & operator = (hashtable &&) = default;
+ hashtable(const hashtable &);
+ hashtable & operator = (const hashtable &);
hashtable(size_t reservedSpace);
hashtable(size_t reservedSpace, const Hash & hasher, const Equal & equal);
virtual ~hashtable();
@@ -248,20 +249,14 @@ public:
const_iterator find(const AltKey & key) const { return find<AltKey, AltExtract, AltHash, AltEqual>(key, AltExtract()); }
const_iterator find(const Key & key) const;
template <typename V>
- insert_result insert(V && node) { return insertInternal(std::forward<V>(node)); }
- void erase(const Key & key) {
- const_iterator found(find(key));
- if (found != end()) {
- DefaultMoveHandler moveHandler;
- erase(moveHandler, found);
- }
- }
+ insert_result insert(V && node);
+ void erase(const Key & key);
void reserve(size_t sz) {
if (sz > _nodes.capacity()) {
resize(sz);
}
}
- void clear() { _nodes.clear(); resize(getTableSize()); }
+ void clear();
void resize(size_t newSize);
void swap(hashtable & rhs);
@@ -307,244 +302,4 @@ private:
void reclaim(MoveHandler & moveHandler, next_t node);
};
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-void hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::swap(hashtable & rhs)
-{
- std::swap(_modulator, rhs._modulator);
- std::swap(_count, rhs._count);
- _nodes.swap(rhs._nodes);
- std::swap(_hasher, rhs._hasher);
- std::swap(_equal, rhs._equal);
- std::swap(_keyExtractor, rhs._keyExtractor);
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::hashtable(size_t reservedSpace) :
- _modulator(1),
- _count(0),
- _nodes(1)
-{
- if (reservedSpace > 0) {
- resize(reservedSpace);
- }
}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::hashtable(size_t reservedSpace, const Hash & hasher, const Equal & equal) :
- _modulator(1),
- _count(0),
- _nodes(1),
- _hasher(hasher),
- _equal(equal)
-{
- if (reservedSpace > 0) {
- resize(reservedSpace);
- }
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::~hashtable()
-{
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::iterator
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const Key & key)
-{
- next_t h = hash(key);
- if (_nodes[h].valid()) {
- next_t start(h);
- do {
- if (_equal(_keyExtractor(_nodes[h].getValue()), key)) {
- return iterator(this, start, h);
- }
- h = _nodes[h].getNext();
- } while (h != Node::npos);
- }
- return end();
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::const_iterator
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const Key & key) const
-{
- next_t h = hash(key);
- if (_nodes[h].valid()) {
- next_t start(h);
- do {
- if (_equal(_keyExtractor(_nodes[h].getValue()), key)) {
- return const_iterator(this, start, h);
- }
- h = _nodes[h].getNext();
- } while (h != Node::npos);
- }
- return end();
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-template< typename AltKey, typename AltExtract, typename AltHash, typename AltEqual>
-typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::const_iterator
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const AltKey & key, const AltExtract & altExtract) const
-{
- AltHash altHasher;
- next_t h = modulator(altHasher(key));
- if (_nodes[h].valid()) {
- next_t start(h);
- AltEqual altEqual;
- do {
- if (altEqual(altExtract(_keyExtractor(_nodes[h].getValue())), key)) {
- return const_iterator(this, start, h);
- }
- h = _nodes[h].getNext();
- } while (h != Node::npos);
- }
- return end();
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-template< typename AltKey, typename AltExtract, typename AltHash, typename AltEqual>
-typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::iterator
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const AltKey & key, const AltExtract & altExtract)
-{
- AltHash altHasher;
- next_t h = modulator(altHasher(key));
- if (_nodes[h].valid()) {
- next_t start(h);
- AltEqual altEqual;
- do {
- if (altEqual(altExtract(_keyExtractor(_nodes[h].getValue())), key)) {
- return iterator(this, start, h);
- }
- h = _nodes[h].getNext();
- } while (h != Node::npos);
- }
- return end();
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-template< typename V >
-typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::insert_result
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::insertInternal(V && node)
-{
- const next_t h = hash(_keyExtractor(node));
- if ( ! _nodes[h].valid() ) {
- _nodes[h] = std::forward<V>(node);
- _count++;
- return insert_result(iterator(this, h, h), true);
- } else if (_nodes.size() <= _nodes.capacity()) {
- for (next_t c(h); c != Node::npos; c = _nodes[c].getNext()) {
- if (_equal(_keyExtractor(_nodes[c].getValue()), _keyExtractor(node))) {
- return insert_result(iterator(this, h, c), false);
- }
- }
- if (_nodes.size() < _nodes.capacity()) {
- const next_t p(_nodes[h].getNext());
- const next_t newIdx(_nodes.size());
- _nodes[h].setNext(newIdx);
- new (_nodes.push_back_fast()) Node(std::forward<V>(node), p);
- _count++;
- return insert_result(iterator(this, h, newIdx), true);
- } else {
- resize(_nodes.capacity()*2);
- return insertInternal(std::forward<V>(node));
- }
- } else {
- resize(_nodes.capacity()*2);
- return insertInternal(std::forward<V>(node));
- }
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-template<typename MoveHandler>
-void hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::reclaim(MoveHandler & moveHandler, next_t node)
-{
- size_t last(_nodes.size()-1);
- if (last >= getTableSize()) {
- if (last != node) {
- next_t h = hash(_keyExtractor(_nodes[last].getValue()));
- for (next_t n(_nodes[h].getNext()); n != last; n=_nodes[h].getNext()) {
- h = n;
- }
- move(moveHandler, last, node);
- _nodes[h].setNext(node);
- }
- _nodes.resize(last);
- }
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-template <typename MoveHandler>
-void
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::erase(MoveHandler & moveHandler, const const_iterator & it)
-{
- next_t h = it.getHash();
- next_t prev = Node::npos;
- do {
- if (h == it.getInternalIndex()) {
- if (prev != Node::npos) {
- _nodes[prev].setNext(_nodes[h].getNext());
- reclaim(moveHandler, h);
- } else {
- if (_nodes[h].hasNext()) {
- next_t next = _nodes[h].getNext();
- move(moveHandler, next, h);
- reclaim(moveHandler, next);
- } else {
- _nodes[h].invalidate();
- }
- }
- _count--;
- return;
- }
- prev = h;
- h = _nodes[h].getNext();
- } while (h != Node::npos);
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-void
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::resize(size_t newSize)
-{
- newSize = roundUp2inN(newSize);
- next_t newModulo = Modulator::selectHashTableSize(newSize/3);
- if (newModulo > newSize) {
- newSize = newModulo;
- }
- NodeStore newStore;
- newStore.reserve(roundUp2inN(newSize));
- newStore.resize(newModulo);
- _modulator = Modulator(newModulo);
- _count = 0;
- _nodes.swap(newStore);
- move(std::move(newStore));
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-void
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::move(NodeStore && oldStore)
-{
- for(typename NodeStore::iterator it(oldStore.begin()), mt(oldStore.end()); it != mt; it++) {
- if (it->valid()) {
- insert(std::move(it->getValue()));
- }
- }
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-size_t
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::getMemoryConsumption() const
-{
- return sizeof(hashtable<Key, Value, Hash, Equal, KeyExtract>)
- + _nodes.capacity() * sizeof(Node);
-}
-
-template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
-size_t
-hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::getMemoryUsed() const
-{
- return sizeof(hashtable<Key, Value, Hash, Equal, KeyExtract>)
- + _nodes.size() * sizeof(Node);
-}
-
-}
-
diff --git a/vespalib/src/vespa/vespalib/stllike/hashtable.hpp b/vespalib/src/vespa/vespalib/stllike/hashtable.hpp
new file mode 100644
index 00000000000..76454ff7fff
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/stllike/hashtable.hpp
@@ -0,0 +1,289 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include "hashtable.h"
+#include <vespa/vespalib/util/array.hpp>
+
+namespace vespalib {
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+void hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::swap(hashtable & rhs)
+{
+ std::swap(_modulator, rhs._modulator);
+ std::swap(_count, rhs._count);
+ _nodes.swap(rhs._nodes);
+ std::swap(_hasher, rhs._hasher);
+ std::swap(_equal, rhs._equal);
+ std::swap(_keyExtractor, rhs._keyExtractor);
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::hashtable(size_t reservedSpace) :
+ _modulator(1),
+ _count(0),
+ _nodes(1)
+{
+ if (reservedSpace > 0) {
+ resize(reservedSpace);
+ }
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::hashtable(size_t reservedSpace, const Hash & hasher, const Equal & equal) :
+ _modulator(1),
+ _count(0),
+ _nodes(1),
+ _hasher(hasher),
+ _equal(equal)
+{
+ if (reservedSpace > 0) {
+ resize(reservedSpace);
+ }
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::hashtable(const hashtable & rhs)
+ : _modulator(rhs._modulator),
+ _count(rhs._count),
+ _nodes(rhs._nodes),
+ _hasher(rhs._hasher),
+ _equal(rhs._equal)
+{ }
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator> &
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::operator = (const hashtable & rhs) {
+ hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>(rhs).swap(*this);
+ return *this;
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::~hashtable()
+{
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::iterator
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const Key & key)
+{
+ next_t h = hash(key);
+ if (_nodes[h].valid()) {
+ next_t start(h);
+ do {
+ if (_equal(_keyExtractor(_nodes[h].getValue()), key)) {
+ return iterator(this, start, h);
+ }
+ h = _nodes[h].getNext();
+ } while (h != Node::npos);
+ }
+ return end();
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::const_iterator
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const Key & key) const
+{
+ next_t h = hash(key);
+ if (_nodes[h].valid()) {
+ next_t start(h);
+ do {
+ if (_equal(_keyExtractor(_nodes[h].getValue()), key)) {
+ return const_iterator(this, start, h);
+ }
+ h = _nodes[h].getNext();
+ } while (h != Node::npos);
+ }
+ return end();
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+template< typename AltKey, typename AltExtract, typename AltHash, typename AltEqual>
+typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::const_iterator
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const AltKey & key, const AltExtract & altExtract) const
+{
+ AltHash altHasher;
+ next_t h = modulator(altHasher(key));
+ if (_nodes[h].valid()) {
+ next_t start(h);
+ AltEqual altEqual;
+ do {
+ if (altEqual(altExtract(_keyExtractor(_nodes[h].getValue())), key)) {
+ return const_iterator(this, start, h);
+ }
+ h = _nodes[h].getNext();
+ } while (h != Node::npos);
+ }
+ return end();
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+template< typename AltKey, typename AltExtract, typename AltHash, typename AltEqual>
+typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::iterator
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const AltKey & key, const AltExtract & altExtract)
+{
+ AltHash altHasher;
+ next_t h = modulator(altHasher(key));
+ if (_nodes[h].valid()) {
+ next_t start(h);
+ AltEqual altEqual;
+ do {
+ if (altEqual(altExtract(_keyExtractor(_nodes[h].getValue())), key)) {
+ return iterator(this, start, h);
+ }
+ h = _nodes[h].getNext();
+ } while (h != Node::npos);
+ }
+ return end();
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+template<typename V>
+typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::insert_result
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::insert(V && node) {
+ return insertInternal(std::forward<V>(node));
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+void
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::erase(const Key & key) {
+ const_iterator found(find(key));
+ if (found != end()) {
+ DefaultMoveHandler moveHandler;
+ erase(moveHandler, found);
+ }
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+void
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::clear() {
+ _nodes.clear();
+ resize(getTableSize());
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+template< typename V >
+typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::insert_result
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::insertInternal(V && node)
+{
+ const next_t h = hash(_keyExtractor(node));
+ if ( ! _nodes[h].valid() ) {
+ _nodes[h] = std::forward<V>(node);
+ _count++;
+ return insert_result(iterator(this, h, h), true);
+ } else if (_nodes.size() <= _nodes.capacity()) {
+ for (next_t c(h); c != Node::npos; c = _nodes[c].getNext()) {
+ if (_equal(_keyExtractor(_nodes[c].getValue()), _keyExtractor(node))) {
+ return insert_result(iterator(this, h, c), false);
+ }
+ }
+ if (_nodes.size() < _nodes.capacity()) {
+ const next_t p(_nodes[h].getNext());
+ const next_t newIdx(_nodes.size());
+ _nodes[h].setNext(newIdx);
+ new (_nodes.push_back_fast()) Node(std::forward<V>(node), p);
+ _count++;
+ return insert_result(iterator(this, h, newIdx), true);
+ } else {
+ resize(_nodes.capacity()*2);
+ return insertInternal(std::forward<V>(node));
+ }
+ } else {
+ resize(_nodes.capacity()*2);
+ return insertInternal(std::forward<V>(node));
+ }
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+template<typename MoveHandler>
+void hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::reclaim(MoveHandler & moveHandler, next_t node)
+{
+ size_t last(_nodes.size()-1);
+ if (last >= getTableSize()) {
+ if (last != node) {
+ next_t h = hash(_keyExtractor(_nodes[last].getValue()));
+ for (next_t n(_nodes[h].getNext()); n != last; n=_nodes[h].getNext()) {
+ h = n;
+ }
+ move(moveHandler, last, node);
+ _nodes[h].setNext(node);
+ }
+ _nodes.resize(last);
+ }
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+template <typename MoveHandler>
+void
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::erase(MoveHandler & moveHandler, const const_iterator & it)
+{
+ next_t h = it.getHash();
+ next_t prev = Node::npos;
+ do {
+ if (h == it.getInternalIndex()) {
+ if (prev != Node::npos) {
+ _nodes[prev].setNext(_nodes[h].getNext());
+ reclaim(moveHandler, h);
+ } else {
+ if (_nodes[h].hasNext()) {
+ next_t next = _nodes[h].getNext();
+ move(moveHandler, next, h);
+ reclaim(moveHandler, next);
+ } else {
+ _nodes[h].invalidate();
+ }
+ }
+ _count--;
+ return;
+ }
+ prev = h;
+ h = _nodes[h].getNext();
+ } while (h != Node::npos);
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+void
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::resize(size_t newSize)
+{
+ newSize = roundUp2inN(newSize);
+ next_t newModulo = Modulator::selectHashTableSize(newSize/3);
+ if (newModulo > newSize) {
+ newSize = newModulo;
+ }
+ NodeStore newStore;
+ newStore.reserve(roundUp2inN(newSize));
+ newStore.resize(newModulo);
+ _modulator = Modulator(newModulo);
+ _count = 0;
+ _nodes.swap(newStore);
+ move(std::move(newStore));
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+void
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::move(NodeStore && oldStore)
+{
+ for(typename NodeStore::iterator it(oldStore.begin()), mt(oldStore.end()); it != mt; it++) {
+ if (it->valid()) {
+ insert(std::move(it->getValue()));
+ }
+ }
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+size_t
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::getMemoryConsumption() const
+{
+ return sizeof(hashtable<Key, Value, Hash, Equal, KeyExtract>)
+ + _nodes.capacity() * sizeof(Node);
+}
+
+template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
+size_t
+hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::getMemoryUsed() const
+{
+ return sizeof(hashtable<Key, Value, Hash, Equal, KeyExtract>)
+ + _nodes.size() * sizeof(Node);
+}
+
+}
+
diff --git a/vespalib/src/vespa/vespalib/tensor/dense/dense_tensor_builder.cpp b/vespalib/src/vespa/vespalib/tensor/dense/dense_tensor_builder.cpp
index fe626e626cc..db2a4ffaac8 100644
--- a/vespalib/src/vespa/vespalib/tensor/dense/dense_tensor_builder.cpp
+++ b/vespalib/src/vespa/vespalib/tensor/dense/dense_tensor_builder.cpp
@@ -1,11 +1,7 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/fastos/fastos.h>
#include "dense_tensor_builder.h"
#include <vespa/vespalib/util/exceptions.h>
-#include <vespa/vespalib/util/stringfmt.h>
-#include <memory>
-#include <string>
using vespalib::IllegalArgumentException;
using vespalib::make_string;
diff --git a/vespalib/src/vespa/vespalib/tensor/dense/dense_tensor_cells_iterator.h b/vespalib/src/vespa/vespalib/tensor/dense/dense_tensor_cells_iterator.h
index 446db249e02..c3d00fdb28d 100644
--- a/vespalib/src/vespa/vespalib/tensor/dense/dense_tensor_cells_iterator.h
+++ b/vespalib/src/vespa/vespalib/tensor/dense/dense_tensor_cells_iterator.h
@@ -6,6 +6,7 @@
#include <vespa/vespalib/tensor/types.h>
#include <vespa/vespalib/eval/value_type.h>
#include <vespa/vespalib/tensor/tensor.h>
+#include <vespa/vespalib/util/arrayref.h>
namespace vespalib {
namespace tensor {
diff --git a/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor.cpp b/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor.cpp
index 24c48bfb92c..4387b4b1fad 100644
--- a/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor.cpp
+++ b/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor.cpp
@@ -1,6 +1,5 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/fastos/fastos.h>
#include "sparse_tensor.h"
#include "sparse_tensor_address_builder.h"
#include "sparse_tensor_match.h"
@@ -10,6 +9,9 @@
#include <vespa/vespalib/tensor/tensor_apply.h>
#include <vespa/vespalib/tensor/tensor_visitor.h>
#include <vespa/vespalib/eval/operation.h>
+#include <vespa/vespalib/stllike/hash_map.hpp>
+#include <vespa/vespalib/stllike/hash_map_equal.hpp>
+#include <vespa/vespalib/util/array_equal.hpp>
#include <sstream>
using vespalib::eval::TensorSpec;
@@ -306,4 +308,7 @@ SparseTensor::reduce(const eval::BinaryOperation &op,
}
} // namespace vespalib::tensor
+
} // namespace vespalib
+
+VESPALIB_HASH_MAP_INSTANTIATE(vespalib::tensor::SparseTensorAddressRef, double);
diff --git a/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor.h b/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor.h
index 5ed3d16b29c..e6682011ba2 100644
--- a/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor.h
+++ b/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor.h
@@ -22,7 +22,7 @@ namespace tensor {
class SparseTensor : public Tensor
{
public:
- typedef vespalib::hash_map<SparseTensorAddressRef, double> Cells;
+ using Cells = vespalib::hash_map<SparseTensorAddressRef, double>;
static constexpr size_t STASH_CHUNK_SIZE = 16384u;
diff --git a/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_address_reducer.cpp b/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_address_reducer.cpp
index 6073acc4669..277bf7963e0 100644
--- a/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_address_reducer.cpp
+++ b/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_address_reducer.cpp
@@ -1,8 +1,8 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/fastos/fastos.h>
#include "sparse_tensor_address_reducer.h"
#include <vespa/vespalib/eval/value_type.h>
+#include <vespa/vespalib/stllike/hash_set.hpp>
namespace vespalib {
namespace tensor {
diff --git a/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_builder.cpp b/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_builder.cpp
index 537da7d8085..beddc79cc9a 100644
--- a/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_builder.cpp
+++ b/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_builder.cpp
@@ -1,7 +1,6 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "sparse_tensor_builder.h"
-#include <vespa/vespalib/tensor/tensor.h>
namespace vespalib {
namespace tensor {
diff --git a/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_match.cpp b/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_match.cpp
index 30cbad770a3..4add729d290 100644
--- a/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_match.cpp
+++ b/vespalib/src/vespa/vespalib/tensor/sparse/sparse_tensor_match.cpp
@@ -1,8 +1,6 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/fastos/fastos.h>
#include "sparse_tensor_match.h"
-#include "sparse_tensor_address_decoder.h"
namespace vespalib {
namespace tensor {
diff --git a/vespalib/src/vespa/vespalib/tensor/tensor_apply.cpp b/vespalib/src/vespa/vespalib/tensor/tensor_apply.cpp
index 23edf418c0b..8384d997122 100644
--- a/vespalib/src/vespa/vespalib/tensor/tensor_apply.cpp
+++ b/vespalib/src/vespa/vespalib/tensor/tensor_apply.cpp
@@ -1,6 +1,5 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/fastos/fastos.h>
#include "tensor_apply.h"
namespace vespalib {
diff --git a/vespalib/src/vespa/vespalib/tensor/tensor_mapper.cpp b/vespalib/src/vespa/vespalib/tensor/tensor_mapper.cpp
index 9c263fb3ffa..f8a1f99cb5b 100644
--- a/vespalib/src/vespa/vespalib/tensor/tensor_mapper.cpp
+++ b/vespalib/src/vespa/vespalib/tensor/tensor_mapper.cpp
@@ -1,7 +1,5 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/fastos/fastos.h>
-
#include "tensor_mapper.h"
#include "tensor.h"
#include "tensor_visitor.h"
diff --git a/vespalib/src/vespa/vespalib/tensor/types.h b/vespalib/src/vespa/vespalib/tensor/types.h
index 6dcdfb5f0d8..7bdb37b8ac2 100644
--- a/vespalib/src/vespa/vespalib/tensor/types.h
+++ b/vespalib/src/vespa/vespalib/tensor/types.h
@@ -4,7 +4,6 @@
#include <vespa/vespalib/stllike/string.h>
#include <map>
-#include <set>
#include <vespa/vespalib/stllike/hash_set.h>
namespace vespalib {
diff --git a/vespalib/src/vespa/vespalib/util/CMakeLists.txt b/vespalib/src/vespa/vespalib/util/CMakeLists.txt
index 261c33c8135..6fb3626a3a1 100644
--- a/vespalib/src/vespa/vespalib/util/CMakeLists.txt
+++ b/vespalib/src/vespa/vespalib/util/CMakeLists.txt
@@ -5,6 +5,7 @@ vespa_add_library(vespalib_vespalib_util OBJECT
alignedmemory.cpp
alloc.cpp
approx.cpp
+ array.cpp
atomic.cpp
backtrace.cpp
barrier.cpp
diff --git a/vespalib/src/vespa/vespalib/util/array.cpp b/vespalib/src/vespa/vespalib/util/array.cpp
new file mode 100644
index 00000000000..529b668f0a8
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/util/array.cpp
@@ -0,0 +1,19 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "array.hpp"
+#include "array_equal.hpp"
+
+namespace vespalib {
+
+template class Array<signed char>;
+template class Array<char>;
+template class Array<int16_t>;
+template class Array<int32_t>;
+template class Array<int64_t>;
+template class Array<unsigned char>;
+template class Array<uint32_t>;
+template class Array<uint64_t>;
+template class Array<float>;
+template class Array<double>;
+
+}
diff --git a/vespalib/src/vespa/vespalib/util/array.h b/vespalib/src/vespa/vespalib/util/array.h
index ea586703c42..2aba4255e25 100644
--- a/vespalib/src/vespa/vespalib/util/array.h
+++ b/vespalib/src/vespa/vespalib/util/array.h
@@ -2,59 +2,14 @@
#pragma once
#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
#include <sys/types.h>
#include <algorithm>
-#include <vector>
#include <vespa/vespalib/util/alloc.h>
#include <vespa/vespalib/util/optimized.h>
#include <tr1/type_traits>
namespace vespalib {
-template <typename T> class Array;
-
-/**
- * This is a simple wrapper class for a typed array with no memory ownership.
- * It is similar to vespalib::stringref
- **/
-template <typename T>
-class ArrayRef {
-public:
- ArrayRef(T * v, size_t sz) : _v(v), _sz(sz) { }
- ArrayRef(std::vector<T> & v) : _v(&v[0]), _sz(v.size()) { }
- inline ArrayRef(Array<T> &v);
- ArrayRef() : _v(nullptr), _sz(0) {}
- T & operator [] (size_t i) { return _v[i]; }
- const T & operator [] (size_t i) const { return _v[i]; }
- size_t size() const { return _sz; }
- T *begin() { return _v; }
- T *end() { return _v + _sz; }
-private:
- T * _v;
- size_t _sz;
-};
-
-template <typename T>
-class ConstArrayRef {
-public:
- ConstArrayRef(const T *v, size_t sz) : _v(v), _sz(sz) { }
- ConstArrayRef(const std::vector<T> & v) : _v(&v[0]), _sz(v.size()) { }
- ConstArrayRef(const ArrayRef<T> & v) : _v(&v[0]), _sz(v.size()) { }
- inline ConstArrayRef(const Array<T> &v);
- ConstArrayRef() : _v(nullptr), _sz(0) {}
- const T & operator [] (size_t i) const { return _v[i]; }
- size_t size() const { return _sz; }
- const T *cbegin() const { return _v; }
- const T *cend() const { return _v + _sz; }
- const T *begin() const { return _v; }
- const T *end() const { return _v + _sz; }
-private:
- const T *_v;
- size_t _sz;
-};
-
/**
* This is a small and compact implementation of a resizeable array.
* It has a smaller footprint than std::vector and most important,
@@ -134,42 +89,23 @@ public:
typedef T value_type;
typedef size_t size_type;
- Array(const Alloc & initial=Alloc::alloc()) : _array(initial.create(0)), _sz(0) { }
+ Array(const Alloc & initial=Alloc::alloc());
Array(size_t sz, const Alloc & initial=Alloc::alloc());
Array(Alloc && buf, size_t sz);
Array(Array &&rhs);
Array(size_t sz, T value, const Alloc & initial=Alloc::alloc());
Array(const_iterator begin, const_iterator end, const Alloc & initial=Alloc::alloc());
Array(const Array & rhs);
- Array & operator =(const Array & rhs) {
- if (&rhs != this) {
- Array t(rhs);
- swap(t);
- }
- return *this;
- }
- Array & operator =(Array && rhs) {
- if (&rhs != this) {
- Array t(std::move(rhs));
- swap(t);
- }
- return *this;
- }
+ Array & operator =(const Array & rhs);
+ Array & operator =(Array && rhs);
~Array();
void swap(Array & rhs) {
_array.swap(rhs._array);
std::swap(_sz, rhs._sz);
}
void resize(size_t n);
- void assign(const_iterator begin_, const_iterator end_) {
- Array tmp(begin_, end_);
- swap(tmp);
- }
- void reserve(size_t n) {
- if (capacity() < n) {
- increase(n);
- }
- }
+ void assign(const_iterator begin_, const_iterator end_);
+ void reserve(size_t n);
void push_back(const T & v) { std::_Construct(push_back(), v); }
iterator push_back() { extend(size()+1); return array(_sz++); }
iterator push_back_fast() { return array(_sz++); }
@@ -202,7 +138,7 @@ public:
T & operator [] (size_t i) { return *array(i); }
const T & operator [] (size_t i) const { return *array(i); }
bool operator == (const Array & rhs) const;
- bool operator != (const Array & rhs) const { return !(*this == rhs); }
+ bool operator != (const Array & rhs) const;
private:
T * array(size_t i) { return static_cast<T *>(_array.get()) + i; }
const T * array(size_t i) const { return static_cast<const T *>(_array.get()) + i; }
@@ -217,179 +153,4 @@ private:
size_t _sz;
};
-template <typename T>
-ArrayRef<T>::ArrayRef(Array<T> &v)
- : _v(&v[0]),
- _sz(v.size())
-{
-}
-
-template <typename T>
-ConstArrayRef<T>::ConstArrayRef(const Array<T> &v)
- : _v(&v[0]),
- _sz(v.size())
-{
-}
-
-template <typename T>
-void construct(T * dest, const T * source, size_t sz, std::tr1::false_type)
-{
- for (size_t i(0); i < sz; i++) {
- std::_Construct(dest + i, *(source + i));
- }
-}
-
-template <typename T>
-void construct(T * dest, const T * source, size_t sz, std::tr1::true_type)
-{
- memcpy(dest, source, sz*sizeof(T));
-}
-
-template <typename T>
-void construct(T * dest, size_t sz, std::tr1::false_type)
-{
- for (size_t i(0); i < sz; i++) {
- void *ptr = &dest[i];
- new(ptr) T();
- }
-}
-
-template <typename T>
-void construct(T * dest, size_t sz, std::tr1::true_type)
-{
- (void) dest;
- (void) sz;
-}
-
-template <typename T>
-void construct(T * dest, size_t sz, T val, std::tr1::false_type)
-{
- for (size_t i(0); i < sz; i++) {
- void *ptr = &dest[i];
- new(ptr) T(val);
- }
-}
-
-template <typename T>
-void construct(T * dest, size_t sz, T val, std::tr1::true_type)
-{
- for (size_t i(0); i < sz; i++) {
- dest[i] = val;
- }
-}
-
-template <typename T>
-Array<T>::Array(const Array & rhs)
- : _array(rhs._array.create(rhs.size() * sizeof(T))),
- _sz(rhs.size())
-{
- construct(array(0), rhs.array(0), _sz, std::tr1::has_trivial_destructor<T>());
-}
-
-template <typename T>
-bool Array<T>::operator ==(const Array & rhs) const
-{
- bool retval(size() == rhs.size());
- for (size_t i(0); retval && (i < _sz); i++) {
- if (*array(i) != rhs[i]) {
- retval = false;
- }
- }
- return retval;
-}
-
-template <typename T>
-void Array<T>::resize(size_t n)
-{
- if (n > capacity()) {
- reserve(n);
- }
- if (n > _sz) {
- construct(array(_sz), n-_sz, std::tr1::has_trivial_destructor<T>());
- } else if (n < _sz) {
- std::_Destroy(array(n), array(_sz));
- }
- _sz = n;
-}
-
-template <typename T>
-void move(T * dest, T * source, size_t sz, std::tr1::false_type)
-{
- for (size_t i(0); i < sz; i++) {
- std::_Construct(dest + i, std::move(*(source + i)));
- std::_Destroy(source + i);
- }
-}
-
-template <typename T>
-void move(T * dest, const T * source, size_t sz, std::tr1::true_type)
-{
- memcpy(dest, source, sz*sizeof(T));
-}
-
-template <typename T>
-void Array<T>::increase(size_t n)
-{
- Alloc newArray(_array.create(sizeof(T)*n));
- if (capacity() > 0) {
- move(static_cast<T *>(newArray.get()), array(0), _sz, std::tr1::has_trivial_destructor<T>());
- }
- _array.swap(newArray);
-}
-
-template <typename T>
-Array<T>::Array(Alloc && buf, size_t sz) :
- _array(std::move(buf)),
- _sz(sz)
-{
-}
-
-
-template <typename T>
-Array<T>::Array(Array &&rhs)
- : _array(std::move(rhs._array)),
- _sz(rhs._sz)
-{
- rhs._sz = 0;
-}
-
-template <typename T>
-Array<T>::Array(size_t sz, const Alloc & initial) :
- _array(initial.create(sz * sizeof(T))),
- _sz(sz)
-{
- construct(array(0), _sz, std::tr1::has_trivial_destructor<T>());
-}
-
-template <typename T>
-Array<T>::Array(size_t sz, T value, const Alloc & initial) :
- _array(initial.create(sz * sizeof(T))),
- _sz(sz)
-{
- construct(array(0), _sz, value, std::tr1::has_trivial_destructor<T>());
-}
-
-template <typename T>
-Array<T>::Array(const_iterator begin_, const_iterator end_, const Alloc & initial) :
- _array(initial.create(begin_ != end_ ? sizeof(T) * (end_-begin_) : 0)),
- _sz(end_-begin_)
-{
- construct(array(0), begin_, _sz, std::tr1::has_trivial_destructor<T>());
-}
-
-template <typename T>
-Array<T>::~Array()
-{
- cleanup();
-}
-
-template <typename T>
-void Array<T>::cleanup()
-{
- std::_Destroy(array(0), array(_sz));
- _sz = 0;
- Alloc().swap(_array);
-}
-
}
-
diff --git a/vespalib/src/vespa/vespalib/util/array.hpp b/vespalib/src/vespa/vespalib/util/array.hpp
new file mode 100644
index 00000000000..dbdda73ad66
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/util/array.hpp
@@ -0,0 +1,196 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include "array.h"
+#include <stdlib.h>
+#include <string.h>
+
+namespace vespalib {
+
+template <typename T>
+void construct(T * dest, const T * source, size_t sz, std::tr1::false_type)
+{
+ for (size_t i(0); i < sz; i++) {
+ std::_Construct(dest + i, *(source + i));
+ }
+}
+
+template <typename T>
+void construct(T * dest, const T * source, size_t sz, std::tr1::true_type)
+{
+ memcpy(dest, source, sz*sizeof(T));
+}
+
+template <typename T>
+void construct(T * dest, size_t sz, std::tr1::false_type)
+{
+ for (size_t i(0); i < sz; i++) {
+ void *ptr = &dest[i];
+ new(ptr) T();
+ }
+}
+
+template <typename T>
+void construct(T * dest, size_t sz, std::tr1::true_type)
+{
+ (void) dest;
+ (void) sz;
+}
+
+template <typename T>
+void construct(T * dest, size_t sz, T val, std::tr1::false_type)
+{
+ for (size_t i(0); i < sz; i++) {
+ void *ptr = &dest[i];
+ new(ptr) T(val);
+ }
+}
+
+template <typename T>
+void construct(T * dest, size_t sz, T val, std::tr1::true_type)
+{
+ for (size_t i(0); i < sz; i++) {
+ dest[i] = val;
+ }
+}
+
+template <typename T>
+Array<T>::Array(const Array & rhs)
+ : _array(rhs._array.create(rhs.size() * sizeof(T))),
+ _sz(rhs.size())
+{
+ construct(array(0), rhs.array(0), _sz, std::tr1::has_trivial_destructor<T>());
+}
+
+template <typename T>
+Array<T> & Array<T>::operator =(const Array & rhs)
+{
+ if (&rhs != this) {
+ Array t(rhs);
+ swap(t);
+ }
+ return *this;
+}
+
+template <typename T>
+Array<T> & Array<T>::operator =(Array && rhs) {
+ if (&rhs != this) {
+ Array t(std::move(rhs));
+ swap(t);
+ }
+ return *this;
+}
+
+template <typename T>
+void Array<T>::assign(const_iterator begin_, const_iterator end_) {
+ Array tmp(begin_, end_);
+ swap(tmp);
+}
+template <typename T>
+void Array<T>::reserve(size_t n) {
+ if (capacity() < n) {
+ increase(n);
+ }
+}
+
+template <typename T>
+void Array<T>::resize(size_t n)
+{
+ if (n > capacity()) {
+ reserve(n);
+ }
+ if (n > _sz) {
+ construct(array(_sz), n-_sz, std::tr1::has_trivial_destructor<T>());
+ } else if (n < _sz) {
+ std::_Destroy(array(n), array(_sz));
+ }
+ _sz = n;
+}
+
+template <typename T>
+void move(T * dest, T * source, size_t sz, std::tr1::false_type)
+{
+ for (size_t i(0); i < sz; i++) {
+ std::_Construct(dest + i, std::move(*(source + i)));
+ std::_Destroy(source + i);
+ }
+}
+
+template <typename T>
+void move(T * dest, const T * source, size_t sz, std::tr1::true_type)
+{
+ memcpy(dest, source, sz*sizeof(T));
+}
+
+template <typename T>
+void Array<T>::increase(size_t n)
+{
+ Alloc newArray(_array.create(sizeof(T)*n));
+ if (capacity() > 0) {
+ move(static_cast<T *>(newArray.get()), array(0), _sz, std::tr1::has_trivial_destructor<T>());
+ }
+ _array.swap(newArray);
+}
+
+template <typename T>
+Array<T>::Array(const Alloc & initial)
+ : _array(initial.create(0)),
+ _sz(0)
+{ }
+
+template <typename T>
+Array<T>::Array(Alloc && buf, size_t sz) :
+ _array(std::move(buf)),
+ _sz(sz)
+{
+}
+
+
+template <typename T>
+Array<T>::Array(Array &&rhs)
+ : _array(std::move(rhs._array)),
+ _sz(rhs._sz)
+{
+ rhs._sz = 0;
+}
+
+template <typename T>
+Array<T>::Array(size_t sz, const Alloc & initial) :
+ _array(initial.create(sz * sizeof(T))),
+ _sz(sz)
+{
+ construct(array(0), _sz, std::tr1::has_trivial_destructor<T>());
+}
+
+template <typename T>
+Array<T>::Array(size_t sz, T value, const Alloc & initial) :
+ _array(initial.create(sz * sizeof(T))),
+ _sz(sz)
+{
+ construct(array(0), _sz, value, std::tr1::has_trivial_destructor<T>());
+}
+
+template <typename T>
+Array<T>::Array(const_iterator begin_, const_iterator end_, const Alloc & initial) :
+ _array(initial.create(begin_ != end_ ? sizeof(T) * (end_-begin_) : 0)),
+ _sz(end_-begin_)
+{
+ construct(array(0), begin_, _sz, std::tr1::has_trivial_destructor<T>());
+}
+
+template <typename T>
+Array<T>::~Array()
+{
+ cleanup();
+}
+
+template <typename T>
+void Array<T>::cleanup()
+{
+ std::_Destroy(array(0), array(_sz));
+ _sz = 0;
+ Alloc().swap(_array);
+}
+
+}
+
diff --git a/vespalib/src/vespa/vespalib/util/array_equal.hpp b/vespalib/src/vespa/vespalib/util/array_equal.hpp
new file mode 100644
index 00000000000..0c790191b99
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/util/array_equal.hpp
@@ -0,0 +1,25 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include "array.h"
+
+namespace vespalib {
+
+template <typename T>
+bool Array<T>::operator ==(const Array & rhs) const
+{
+ bool retval(size() == rhs.size());
+ for (size_t i(0); retval && (i < _sz); i++) {
+ if ( ! (*array(i) == rhs[i]) ) {
+ retval = false;
+ }
+ }
+ return retval;
+}
+
+template <typename T>
+bool Array<T>::operator != (const Array & rhs) const {
+ return !(*this == rhs);
+}
+
+}
diff --git a/vespalib/src/vespa/vespalib/util/arrayref.h b/vespalib/src/vespa/vespalib/util/arrayref.h
new file mode 100644
index 00000000000..3b4bd022d1b
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/util/arrayref.h
@@ -0,0 +1,49 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include "array.h"
+#include <vector>
+
+namespace vespalib {
+
+/**
+ * This is a simple wrapper class for a typed array with no memory ownership.
+ * It is similar to vespalib::stringref
+ **/
+template <typename T>
+class ArrayRef {
+public:
+ ArrayRef() : _v(nullptr), _sz(0) { }
+ ArrayRef(T * v, size_t sz) : _v(v), _sz(sz) { }
+ ArrayRef(std::vector<T> & v) : _v(&v[0]), _sz(v.size()) { }
+ ArrayRef(Array<T> &v) : _v(&v[0]), _sz(v.size()) { }
+ T & operator [] (size_t i) { return _v[i]; }
+ const T & operator [] (size_t i) const { return _v[i]; }
+ size_t size() const { return _sz; }
+ T *begin() { return _v; }
+ T *end() { return _v + _sz; }
+private:
+ T * _v;
+ size_t _sz;
+};
+
+template <typename T>
+class ConstArrayRef {
+public:
+ ConstArrayRef(const T *v, size_t sz) : _v(v), _sz(sz) { }
+ ConstArrayRef(const std::vector<T> & v) : _v(&v[0]), _sz(v.size()) { }
+ ConstArrayRef(const ArrayRef<T> & v) : _v(&v[0]), _sz(v.size()) { }
+ ConstArrayRef(const Array<T> &v) : _v(&v[0]), _sz(v.size()) { }
+ ConstArrayRef() : _v(nullptr), _sz(0) {}
+ const T & operator [] (size_t i) const { return _v[i]; }
+ size_t size() const { return _sz; }
+ const T *cbegin() const { return _v; }
+ const T *cend() const { return _v + _sz; }
+ const T *begin() const { return _v; }
+ const T *end() const { return _v + _sz; }
+private:
+ const T *_v;
+ size_t _sz;
+};
+
+}
diff --git a/vespalib/src/vespa/vespalib/util/generationholder.h b/vespalib/src/vespa/vespalib/util/generationholder.h
index d178fc7f4e5..557104e2687 100644
--- a/vespalib/src/vespa/vespalib/util/generationholder.h
+++ b/vespalib/src/vespa/vespalib/util/generationholder.h
@@ -3,6 +3,7 @@
#pragma once
#include <vector>
+#include <memory>
#include "generationhandler.h"
namespace vespalib {
@@ -22,8 +23,7 @@ public:
GenerationHeldBase(size_t size)
: _generation(0u),
_size(size)
- {
- }
+ { }
virtual ~GenerationHeldBase(void);
size_t getSize(void) const { return _size; }
diff --git a/vespalib/src/vespa/vespalib/util/stash.h b/vespalib/src/vespa/vespalib/util/stash.h
index 1ec0f7b0056..4daccc22d0b 100644
--- a/vespalib/src/vespa/vespalib/util/stash.h
+++ b/vespalib/src/vespa/vespalib/util/stash.h
@@ -2,9 +2,8 @@
#pragma once
-#include <vespa/fastos/fastos.h>
#include "traits.h"
-#include "array.h"
+#include "arrayref.h"
namespace vespalib {
namespace stash {