[PATCH] D48504: [WIP] Add InsertionOrderSet, with constant-time insertion and removal.
Eli Friedman via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 22 12:42:26 PDT 2018
efriedma created this revision.
This is useful in places which need a consistent iteration order like a SetVector, but also need constant-time removal.
I just quickly hacked this together as a proof of concept for https://reviews.llvm.org/D48372; there's a lot of room for improvement.
Repository:
rL LLVM
https://reviews.llvm.org/D48504
Files:
include/llvm/ADT/InsertionOrderSet.h
Index: include/llvm/ADT/InsertionOrderSet.h
===================================================================
--- /dev/null
+++ include/llvm/ADT/InsertionOrderSet.h
@@ -0,0 +1,82 @@
+//===- InsertionOrderSet.h - Hash table--------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+#include <vector>
+
+namespace llvm {
+
+/// A hash table with constant-time insertion and removal, and iteration in
+/// insertion order. This is by contrast to a SetVector, which does not have
+/// constant-time removal (but has random-access iterators).
+///
+/// Issues with the current implementation:
+/// - It makes two copies of each item in the set.
+/// - It doesn't clean out dead entries in the vector when the set is rehashed.
+/// - InsertionOrderMap is missing.
+/// - The name could probably be improved.
+template <class ValueT>
+class InsertionOrderSet {
+ DenseMap<ValueT, size_t> Map;
+ typedef std::vector<Optional<ValueT>> VecType;
+ VecType Vec;
+
+ struct Filter {
+ bool operator()(const Optional<ValueT>& In) {
+ return In.hasValue();
+ }
+ };
+ typedef filter_iterator<typename VecType::iterator, Filter> FilteredIter;
+
+public:
+ typedef pointee_iterator<FilteredIter> iterator;
+
+private:
+ iterator MakeSetIterator(typename VecType::iterator I) {
+ return FilteredIter{I, Vec.end(), Filter{}};
+ }
+
+public:
+ std::pair<iterator, bool> insert(ValueT value) {
+ auto SetIns = Map.insert(std::make_pair(value, Vec.size()));
+ if (SetIns.second) {
+ Vec.push_back(value);
+ return { MakeSetIterator(Vec.end()-1), true };
+ }
+ return { MakeSetIterator(Vec.begin()+SetIns.first->second), false };
+ }
+
+ iterator begin() {
+ return MakeSetIterator(Vec.begin());
+ }
+ iterator end() {
+ return MakeSetIterator(Vec.end());
+ }
+
+ void clear() {
+ Vec.clear();
+ Map.clear();
+ }
+
+ size_t size() const {
+ return Vec.size();
+ }
+
+ void remove(ValueT value) {
+ auto MapFind = Map.find(value);
+ if (MapFind != Map.end()) {
+ size_t Index = MapFind->second;
+ Map.erase(MapFind);
+ Vec[Index] = None;
+ }
+ }
+};
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48504.152534.patch
Type: text/x-patch
Size: 2446 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180622/5177493b/attachment.bin>
More information about the llvm-commits
mailing list