Use std::shared_ptr to deallocate partialSolns automatically

This commit is contained in:
Jack Grigg
2016-07-23 00:31:47 +12:00
parent 1655db285d
commit 215b9e139d
2 changed files with 15 additions and 25 deletions

View File

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

View File

@@ -14,6 +14,7 @@
#include <cstring> #include <cstring>
#include <exception> #include <exception>
#include <functional> #include <functional>
#include <memory>
#include <set> #include <set>
#include <vector> #include <vector>
@@ -107,7 +108,7 @@ public:
TruncatedStepRow& operator=(const TruncatedStepRow<WIDTH>& a); 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; } 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 enum EhSolverCancelCheck