Browse Source

Use std::shared_ptr to deallocate partialSolns automatically

pull/145/head
Jack Grigg 8 years ago
parent
commit
215b9e139d
  1. 37
      src/crypto/equihash.cpp
  2. 3
      src/crypto/equihash.h

37
src/crypto/equihash.cpp

@ -185,10 +185,10 @@ TruncatedStepRow<WIDTH>& TruncatedStepRow<WIDTH>::operator=(const TruncatedStepR
}
template<size_t WIDTH>
eh_trunc* TruncatedStepRow<WIDTH>::GetTruncatedIndices(size_t len, size_t lenIndices) const
std::shared_ptr<eh_trunc> TruncatedStepRow<WIDTH>::GetTruncatedIndices(size_t len, size_t lenIndices) const
{
eh_trunc* p = new eh_trunc[lenIndices];
std::copy(hash+len, hash+len+lenIndices, p);
std::shared_ptr<eh_trunc> p (new eh_trunc[lenIndices]);
std::copy(hash+len, hash+len+lenIndices, p.get());
return p;
}
@ -362,9 +362,7 @@ std::set<std::vector<eh_index>> Equihash<N,K>::OptimisedSolve(const eh_HashState
// First run the algorithm with truncated indices
eh_index soln_size { 1 << K };
// Each element of partialSolns is dynamically allocated in a call to
// GetTruncatedIndices(), and freed at the end of this function.
std::vector<eh_trunc*> partialSolns;
std::vector<std::shared_ptr<eh_trunc>> partialSolns;
std::set<std::vector<eh_index>> solns;
int invalidCount = 0;
{
@ -461,7 +459,7 @@ std::set<std::vector<eh_index>> Equihash<N,K>::OptimisedSolve(const eh_HashState
}
i += j;
if (cancelled(FinalColliding)) goto cancelsolver;
if (cancelled(FinalColliding)) throw solver_cancelled;
}
} else
LogPrint("pow", "- List is empty\n");
@ -472,7 +470,7 @@ std::set<std::vector<eh_index>> Equihash<N,K>::OptimisedSolve(const eh_HashState
// Now for each solution run the algorithm again to recreate the indices
LogPrint("pow", "Culling solutions\n");
for (eh_trunc* partialSoln : partialSolns) {
for (std::shared_ptr<eh_trunc> partialSoln : partialSolns) {
size_t hashLen;
size_t lenIndices;
std::vector<boost::optional<std::vector<FullStepRow<FinalFullWidth>>>> X;
@ -484,9 +482,9 @@ std::set<std::vector<eh_index>> Equihash<N,K>::OptimisedSolve(const eh_HashState
std::vector<FullStepRow<FinalFullWidth>> icv;
icv.reserve(recreate_size);
for (eh_index j = 0; j < recreate_size; j++) {
eh_index newIndex { UntruncateIndex(partialSoln[i], j, CollisionBitLength + 1) };
eh_index newIndex { UntruncateIndex(partialSoln.get()[i], j, CollisionBitLength + 1) };
icv.emplace_back(N, base_state, newIndex);
if (cancelled(PartialGeneration)) goto cancelsolver;
if (cancelled(PartialGeneration)) throw solver_cancelled;
}
boost::optional<std::vector<FullStepRow<FinalFullWidth>>> ic = icv;
@ -502,12 +500,12 @@ std::set<std::vector<eh_index>> Equihash<N,K>::OptimisedSolve(const eh_HashState
ic->reserve(ic->size() + X[r]->size());
ic->insert(ic->end(), X[r]->begin(), X[r]->end());
std::sort(ic->begin(), ic->end(), CompareSR(hashLen));
if (cancelled(PartialSorting)) goto cancelsolver;
if (cancelled(PartialSorting)) throw solver_cancelled;
size_t lti = rti-(1<<r);
CollideBranches(*ic, hashLen, lenIndices,
CollisionByteLength,
CollisionBitLength + 1,
partialSoln[lti], partialSoln[rti]);
partialSoln.get()[lti], partialSoln.get()[rti]);
// 2d) Check if this has become an invalid solution
if (ic->size() == 0)
@ -525,9 +523,9 @@ std::set<std::vector<eh_index>> Equihash<N,K>::OptimisedSolve(const eh_HashState
X.push_back(ic);
break;
}
if (cancelled(PartialSubtreeEnd)) goto cancelsolver;
if (cancelled(PartialSubtreeEnd)) throw solver_cancelled;
}
if (cancelled(PartialIndexEnd)) goto cancelsolver;
if (cancelled(PartialIndexEnd)) throw solver_cancelled;
}
// We are at the top of the tree
@ -535,7 +533,7 @@ std::set<std::vector<eh_index>> Equihash<N,K>::OptimisedSolve(const eh_HashState
for (FullStepRow<FinalFullWidth> row : *X[K]) {
solns.insert(row.GetIndices(hashLen, lenIndices));
}
if (cancelled(PartialEnd)) goto cancelsolver;
if (cancelled(PartialEnd)) throw solver_cancelled;
continue;
invalidsolution:
@ -543,16 +541,7 @@ invalidsolution:
}
LogPrint("pow", "- Number of invalid solutions found: %d\n", invalidCount);
for (eh_trunc* partialSoln : partialSolns) {
delete[] partialSoln;
}
return solns;
cancelsolver:
for (eh_trunc* partialSoln : partialSolns) {
delete[] partialSoln;
}
throw solver_cancelled;
}
template<unsigned int N, unsigned int K>

3
src/crypto/equihash.h

@ -14,6 +14,7 @@
#include <cstring>
#include <exception>
#include <functional>
#include <memory>
#include <set>
#include <vector>
@ -107,7 +108,7 @@ public:
TruncatedStepRow& operator=(const TruncatedStepRow<WIDTH>& a);
inline bool IndicesBefore(const TruncatedStepRow<WIDTH>& a, size_t len, size_t lenIndices) const { return memcmp(hash+len, a.hash+len, lenIndices) < 0; }
eh_trunc* GetTruncatedIndices(size_t len, size_t lenIndices) const;
std::shared_ptr<eh_trunc> GetTruncatedIndices(size_t len, size_t lenIndices) const;
};
enum EhSolverCancelCheck

Loading…
Cancel
Save