[mathicgb] 97/393: MonomialMap now grows automatically again.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:58:39 UTC 2015


This is an automated email from the git hooks/post-receive script.

dtorrance-guest pushed a commit to branch upstream
in repository mathicgb.

commit c3802e61c13c48e5d52cb43c62f24fa8b17e725a
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Sat Nov 3 18:20:08 2012 +0100

    MonomialMap now grows automatically again.
---
 src/mathicgb/F4MatrixBuilder.cpp   |  12 ++--
 src/mathicgb/F4MatrixBuilder.hpp   |   6 +-
 src/mathicgb/MonomialMap.hpp       | 109 +++++++++++++++++++++----------------
 src/mathicgb/QuadMatrixBuilder.hpp |   4 +-
 4 files changed, 73 insertions(+), 58 deletions(-)

diff --git a/src/mathicgb/F4MatrixBuilder.cpp b/src/mathicgb/F4MatrixBuilder.cpp
index 36e7382..4a23b19 100755
--- a/src/mathicgb/F4MatrixBuilder.cpp
+++ b/src/mathicgb/F4MatrixBuilder.cpp
@@ -25,14 +25,14 @@ MATHICGB_INLINE QuadMatrixBuilder::LeftRightColIndex
 (
   const const_monomial monoA,
   const const_monomial monoB,
-  const ColSnapshotReader& colMap,
+  const ColSubsetReader& colMap,
   QuadMatrixBuilder& builder
 ) {
   MATHICGB_ASSERT(!monoA.isNull());
   MATHICGB_ASSERT(!monoB.isNull());
   const auto col = colMap.findProduct(monoA, monoB);
   if (col == 0)
-    return createColumn(builder, monoA, monoB);
+    return findOrCreateColumn(monoA, monoB, builder);
   return *col;
 }
 
@@ -73,7 +73,7 @@ MATHICGB_INLINE const std::pair<
   const const_monomial monoA1,
   const const_monomial monoA2,
   const const_monomial monoB,
-  const ColSnapshotReader& colMap,
+  const ColSubsetReader& colMap,
   QuadMatrixBuilder& builder
 ) {
   MATHICGB_ASSERT(!monoA1.isNull());
@@ -371,7 +371,7 @@ void F4MatrixBuilder::appendRowBottom(
   // todo: eliminate the code-duplication between here and appendRowTop.
   MATHICGB_ASSERT(!multiple.isNull());
   MATHICGB_ASSERT(&builder != 0);
-  const ColSnapshotReader colMap(builder.columnToIndexMap());
+  const ColSubsetReader colMap(builder.columnToIndexMap());
 
   for (auto it  = begin; it != end; ++it) {
     const auto col = findOrCreateColumn(it.getMonomial(), multiple, colMap, builder);
@@ -394,7 +394,7 @@ void F4MatrixBuilder::appendRowTop(
   MATHICGB_ASSERT(&poly != 0);
   MATHICGB_ASSERT(&builder != 0);
 
-  QuadMatrixBuilder::ColSnapshotReader colMap(builder.columnToIndexMap());
+  ColSubsetReader colMap(builder.columnToIndexMap());
 
   auto it = poly.begin();
   const auto end = poly.end();
@@ -454,7 +454,7 @@ void F4MatrixBuilder::appendRowBottom(
   ++itA;
   ++itB;
 
-  const ColSnapshotReader colMap(builder.columnToIndexMap());
+  const ColSubsetReader colMap(builder.columnToIndexMap());
 
   const const_monomial mulA = task.multiply;
   const const_monomial mulB = task.sPairMultiply;
diff --git a/src/mathicgb/F4MatrixBuilder.hpp b/src/mathicgb/F4MatrixBuilder.hpp
index 8138cc6..dee87c1 100755
--- a/src/mathicgb/F4MatrixBuilder.hpp
+++ b/src/mathicgb/F4MatrixBuilder.hpp
@@ -66,7 +66,7 @@ public:
   const PolyRing& ring() const {return mBuilder.ring();}
 
 private:
-  typedef const QuadMatrixBuilder::ColSnapshotReader ColSnapshotReader;
+  typedef const QuadMatrixBuilder::ColSubsetReader ColSubsetReader;
 
   /** Creates a column with monomial label x and schedules a new row to
     reduce that column if possible. Here x is monoA if monoB is
@@ -104,7 +104,7 @@ private:
   MATHICGB_INLINE LeftRightColIndex findOrCreateColumn(
     const_monomial monoA,
     const_monomial monoB,
-    const ColSnapshotReader& colMap,
+    const ColSubsetReader& colMap,
     QuadMatrixBuilder& builder);
 
   MATHICGB_NO_INLINE const std::pair<LeftRightColIndex, LeftRightColIndex>
@@ -119,7 +119,7 @@ private:
     const const_monomial monoA1,
     const const_monomial monoA2,
     const const_monomial monoB,
-    const ColSnapshotReader& colMap,
+    const ColSubsetReader& colMap,
     QuadMatrixBuilder& builder
   );
 
diff --git a/src/mathicgb/MonomialMap.hpp b/src/mathicgb/MonomialMap.hpp
index 037b5cc..d56933d 100755
--- a/src/mathicgb/MonomialMap.hpp
+++ b/src/mathicgb/MonomialMap.hpp
@@ -75,46 +75,30 @@ public:
     delete[] mBuckets;
   }
 
+  /// map must not be mutated except to destruct it after this operation.
+  /// Queries into map will continue to give either a correct result or
+  /// a spurious miss. There will not be spurious hits.
   FixedSizeMonomialMap(
     const size_t requestedBucketCount,
-    const FixedSizeMonomialMap& map
+    FixedSizeMonomialMap<MTT>&& map
   ):
     mHashToIndexMask(computeHashMask(requestedBucketCount)),
     mBuckets(new Node*[hashMaskToBucketCount(mHashToIndexMask)]),
     mRing(map.ring()),
-    mNodeAlloc(sizeofNode(map.ring())),
+    mNodeAlloc(std::move(map.mNodeAlloc)),
     mEntryCount(0)
   {
-    for (size_t bucket = 0; bucket < map.bucketCount(); ++bucket)
-      for (Node* node = map.mBuckets[bucket]; node != 0; node = node->next)
-        insert(std::make_pair(node->mono, node->value));
-    /*
-    todo: use this code once we have a move constructor for mNodeAlloc.
-    // Move nodes from current table into new table
-    decltype(mBuckets) newTable(newTableSize);
-    HashValue newHashToIndexMask = static_cast<HashValue>(newTableSize - 1);
-    const auto tableEnd = mBuckets.end();
-    for (auto tableIt = mBuckets.begin(); tableIt != tableEnd; ++tableIt) {
-      Node* node = *tableIt;
-      while (node != 0) {
-        const size_t index =
-          mRing.monomialHashValue(node->mono) & newHashToIndexMask;
-        MATHICGB_ASSERT(index < newTable.size());
+    std::fill_n(mBuckets, bucketCount(), static_cast<Node*>(0));
+    const auto tableEnd = map.mBuckets + map.bucketCount();
+    for (auto tableIt = map.mBuckets; tableIt != tableEnd; ++tableIt) {
+      for (Node* node = *tableIt; node != 0;) {
+        const size_t index = hashToIndex(mRing.monomialHashValue(node->mono));
         Node* const next = node->next;
-        node->next = newTable[index];
-        newTable[index] = node;
+        node->next = mBuckets[index];
+        mBuckets[index] = node;
         node = next;
       }
     }
-
-    // Move newly calculated table into place
-    mBucketsSize = newTableSize;      
-    mBuckets = std::move(newTable);
-    mHashToIndexMask = newHashToIndexMask;
-    mGrowWhenThisManyEntries = newGrowWhenThisManyEntries;
-
-    MATHICGB_ASSERT(mBucketsSize < mGrowWhenThisManyEntries);
-    */
   }
 
   const PolyRing& ring() const {return mRing;}
@@ -465,15 +449,15 @@ public:
   //typedef typename MapType::Map::const_iterator const_iterator;
   typedef typename MapType::value_type value_type;
 
-  /// A snapshot of a map. Later updates to the map may
-  /// or may not ever become reflected in this snapshot. The acquire/release
-  /// overhead for reading from the table is only performed once per
-  /// snapshot while it is performed every time when reading directly
-  /// from the map.
-  class SnapshotReader {
+  /// Can be used for non-mutating accesses to the monomial map. This reader
+  /// can miss queries that should hit if the map is mutated after the
+  /// reader was constructed - it may only give access to a subset of the
+  /// entries in this case. The only guarantee is that if the reader
+  /// reports a hit then it really is a hit and spurious misses only happen
+  /// after the map has been mutated.
+  class SubsetReader {
   public:
-    SnapshotReader(const MonomialMap<MTT>& map): mMap(&map.mMap) {}
-    void update(const MonomialMap<MTT>& map) {mMap = &map.mMap;}
+    SubsetReader(const MonomialMap<MTT>& map): mMap(map.mMap.get()) {}
 
     const mapped_type* find(const_monomial m) const {
       return mMap->find(m);
@@ -496,21 +480,22 @@ public:
     }
 
   private:
-    SnapshotReader(const FixedSizeMonomialMap<MTT>& map): mMap(&map) {}
-    const FixedSizeMonomialMap<MTT>* mMap;
+    const FixedSizeMonomialMap<MTT>* const mMap;
   };
 
-  MonomialMap(const PolyRing& ring): mMap(200 * 1000, ring) {}
+  MonomialMap(const PolyRing& ring):
+    mMap(make_unique<MapType>(InitialBucketCount, ring)),
+    mCapacityUntilGrowth(maxEntries(mMap->bucketCount())) {}
 
   const mapped_type* find(const_monomial m) const {
-    return mMap.find(m);
+    return mMap->find(m);
   }
 
   const mapped_type* findProduct(
     const const_monomial a,
     const const_monomial b
   ) const {
-    return mMap.findProduct(a, b);
+    return mMap->findProduct(a, b);
   }
 
   MATHICGB_INLINE
@@ -519,19 +504,49 @@ public:
     const const_monomial a2,
     const const_monomial b
   ) const {
-    return mMap.findTwoProducts(a1, a2, b);
+    return mMap->findTwoProducts(a1, a2, b);
   }
 
-  size_t size() const {return mMap.size();}
-  void clear() {mMap.clear();}
+  //size_t size() const {return mMap->size();}
+  void clear() {mMap->clear();}
+
   void insert(const value_type& val) {
-    mMap.insert(val);
+    while (mCapacityUntilGrowth == 0) {
+      const size_t currentSize = size();
+      if (mMap->bucketCount() >
+        std::numeric_limits<size_t>::max() / GrowthFactor)
+      {
+        throw std::bad_alloc();
+      }
+      const size_t newBucketCount = mMap->bucketCount() * GrowthFactor;
+      auto nextMap = make_unique<MapType>(newBucketCount, std::move(*mMap));
+      mOldMaps.push_back(std::move(mMap));
+      mMap = std::move(nextMap);
+      mCapacityUntilGrowth = maxEntries(mMap->bucketCount()) - currentSize;
+    }
+    mMap->insert(val);
+    MATHICGB_ASSERT(mCapacityUntilGrowth > 0);
+    --mCapacityUntilGrowth;
+  }
+
+  size_t size() const {
+    return maxEntries(mMap->bucketCount()) - mCapacityUntilGrowth;
   }
 
-  inline const PolyRing& ring() const {return mMap.ring();}
+  const PolyRing& ring() const {return mMap->ring();}
 
 private:
-  MapType mMap;
+  static const size_t MinBucketsPerEntry = 3; // inverse of max load factor
+  static const size_t GrowthFactor = 2;
+  static const size_t InitialBucketCount = 1 << 16;
+
+  static size_t maxEntries(const size_t bucketCount) {
+    return (bucketCount + (MinBucketsPerEntry - 1)) / MinBucketsPerEntry;
+  }
+
+  std::unique_ptr<MapType> mMap;
+  size_t mCapacityUntilGrowth;
+  std::vector<std::unique_ptr<MapType>> mOldMaps;
 };
 
 #endif
diff --git a/src/mathicgb/QuadMatrixBuilder.hpp b/src/mathicgb/QuadMatrixBuilder.hpp
index 71d9d4a..02bf9a4 100755
--- a/src/mathicgb/QuadMatrixBuilder.hpp
+++ b/src/mathicgb/QuadMatrixBuilder.hpp
@@ -183,8 +183,8 @@ class QuadMatrixBuilder {
 
   // *** Querying columns
 
-  typedef const MonomialMap<LeftRightColIndex>::SnapshotReader
-    ColSnapshotReader;
+  typedef const MonomialMap<LeftRightColIndex>::SubsetReader
+    ColSubsetReader;
   const MonomialMap<LeftRightColIndex>& columnToIndexMap() const {
     return mMonomialToCol;
   }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mathicgb.git



More information about the debian-science-commits mailing list