From f209cb48f9ab9ffb257b0d970a13dc53c206191c Mon Sep 17 00:00:00 2001
From: Simon Praetorius <simon.praetorius@tu-dresden.de>
Date: Sun, 15 Sep 2024 13:31:31 +0200
Subject: [PATCH] Revert "Switch internal data structure in MatrixIndexSet"

This reverts commit c8272a07fa0fd4dc1274612ed5ffb016d4d326c8.
---
 dune/istl/matrixindexset.hh | 132 +++++++-----------------------------
 1 file changed, 24 insertions(+), 108 deletions(-)

diff --git a/dune/istl/matrixindexset.hh b/dune/istl/matrixindexset.hh
index acc4466b4..10baccf35 100644
--- a/dune/istl/matrixindexset.hh
+++ b/dune/istl/matrixindexset.hh
@@ -5,139 +5,55 @@
 #ifndef DUNE_ISTL_MATRIXINDEXSET_HH
 #define DUNE_ISTL_MATRIXINDEXSET_HH
 
-#include <algorithm>
-#include <cstddef>
-#include <cstdint>
-#include <set>
-#include <variant>
 #include <vector>
-
-#include <dune/common/overloadset.hh>
+#include <set>
 
 namespace Dune {
 
 
-  /**
-   * \brief Stores the nonzero entries for creating a sparse matrix
-   *
-   * This stores std::set-like container for the column index
-   * of each row. A sorted std::vector is used for this container
-   * up to a customizable maxVectorSize. If this size is exceeded,
-   * storage of the corresponding row is switched to std::set.
-   *
-   * The default value for maxVectorSize works well and ensures
-   * that the slow std::set fallback is only used for very
-   * dense rows.
-   */
+  /** \brief Stores the nonzero entries in a sparse matrix */
   class MatrixIndexSet
   {
-    using Index = std::size_t;
-
-    // A vector that partly mimics a std::set by staying
-    // sorted on insert() and having unique values.
-    class FlatSet : public std::vector<Index>
-    {
-      using Base = std::vector<Index>;
-    public:
-      using Base::Base;
-      using Base::begin;
-      using Base::end;
-      void insert(const Index& value) {
-        auto it = std::lower_bound(begin(), end(), value);
-        if ((it == end() or (*it != value)))
-          Base::insert(it, value);
-      }
-      bool contains(const Index& value) const {
-        return std::binary_search(begin(), end(), value);
-      }
-    };
-
-    using RowIndexSet = std::variant<FlatSet, std::set<Index>>;
 
   public:
+    typedef std::size_t size_type;
 
-    using size_type = Index;
-
-    /**
-     * \brief Default value for maxVectorSize
-     *
-     * This was selected after benchmarking for the worst case
-     * of reverse insertion of column indices. In many applications
-     * this works well. There's no need to use a different value
-     * unless you have many dense rows with more than defaultMaxVectorSize
-     * nonzero entries. Even in this case defaultMaxVectorSize may work
-     * well and a finding a better value may require careful
-     * benchmarking.
-     */
-    static constexpr size_type defaultMaxVectorSize = 2048;
-
-    /**
-     * \brief Constructor with custom maxVectorSize
-     *
-     * \param maxVectorSize Maximal size for stored row vector (default is defaultMaxVectorSize).
-     */
-    MatrixIndexSet(size_type maxVectorSize=defaultMaxVectorSize) noexcept : rows_(0), cols_(0), maxVectorSize_(maxVectorSize)
+    /** \brief Default constructor */
+    MatrixIndexSet() : rows_(0), cols_(0)
     {}
 
-    /**
-     * \brief Constructor setting the matrix size
-     *
-     * \param rows Number of matrix rows
-     * \param cols Number of matrix columns
-     * \param maxVectorSize Maximal size for stored row vector (default is defaultMaxVectorSize).
-     */
-    MatrixIndexSet(size_type rows, size_type cols, size_type maxVectorSize=defaultMaxVectorSize) : rows_(rows), cols_(cols), maxVectorSize_(maxVectorSize)
-    {
-      indices_.resize(rows_, FlatSet());
+    /** \brief Constructor setting the matrix size */
+    MatrixIndexSet(size_type rows, size_type cols) : rows_(rows), cols_(cols) {
+      indices_.resize(rows_);
     }
 
     /** \brief Reset the size of an index set */
     void resize(size_type rows, size_type cols) {
       rows_ = rows;
       cols_ = cols;
-      indices_.resize(rows_, FlatSet());
+      indices_.resize(rows_);
     }
 
     /** \brief Add an index to the index set */
-    void add(size_type row, size_type col) {
-      return std::visit(Dune::overload(
-        // If row is stored as set, call insert directly
-        [&](std::set<size_type>& set) {
-          set.insert(col);
-        },
-        // If row is stored as vector only insert directly
-        // if maxVectorSize_ is not reached. Otherwise switch
-        // to set storage first.
-        [&](FlatSet& sortedVector) {
-          if (sortedVector.size() < maxVectorSize_)
-            sortedVector.insert(col);
-          else if (not sortedVector.contains(col))
-          {
-            std::set<size_type> set(sortedVector.begin(), sortedVector.end());
-            set.insert(col);
-            indices_[row] = std::move(set);
-          }
-        }
-      ), indices_[row]);
+    void add(size_type i, size_type j) {
+      indices_[i].insert(j);
     }
 
     /** \brief Return the number of entries */
     size_type size() const {
       size_type entries = 0;
       for (size_type i=0; i<rows_; i++)
-        entries += rowsize(i);
+        entries += indices_[i].size();
+
       return entries;
     }
 
     /** \brief Return the number of rows */
     size_type rows() const {return rows_;}
 
+
     /** \brief Return the number of entries in a given row */
-    size_type rowsize(size_type row) const {
-      return std::visit([&](const auto& rowIndices) {
-        return rowIndices.size();
-      }, indices_[row]);
-    }
+    size_type rowsize(size_type row) const {return indices_[row].size();}
 
     /** \brief Import all nonzero entries of a sparse matrix into the index set
         \tparam MatrixType Needs to be BCRSMatrix<...>
@@ -176,16 +92,17 @@ namespace Dune {
       matrix.setSize(rows_, cols_);
       matrix.setBuildMode(MatrixType::random);
 
-      for (size_type row=0; row<rows_; row++)
-        matrix.setrowsize(row, rowsize(row));
+      for (size_type i=0; i<rows_; i++)
+        matrix.setrowsize(i, indices_[i].size());
 
       matrix.endrowsizes();
 
-      for (size_type row=0; row<rows_; row++) {
-        std::visit([&](const auto& rowIndices) {
-          for(size_type col : rowIndices)
-             matrix.addindex(row, col);
-        }, indices_[row]);
+      for (size_type i=0; i<rows_; i++) {
+
+        typename std::set<size_type>::iterator it = indices_[i].begin();
+        for (; it!=indices_[i].end(); ++it)
+          matrix.addindex(i, *it);
+
       }
 
       matrix.endindices();
@@ -194,10 +111,9 @@ namespace Dune {
 
   private:
 
-    std::vector<RowIndexSet> indices_;
+    std::vector<std::set<size_type> > indices_;
 
     size_type rows_, cols_;
-    size_type maxVectorSize_;
 
   };
 
-- 
GitLab