Repository navigation
Expand file tree
/
Copy pathDBXHash.cpp
More file actions
97 lines (86 loc) · 2.64 KB
/
Copy pathDBXHash.cpp
File metadata and controls
97 lines (86 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//
// Created by zeke on 6/28/21.
//
#include "DBXHash.h"
#include "Context.h"
DBXHash::DBXHash(uint32_t _threads) {
lock = shared_ptr<boost::mutex>(new boost::mutex);
signal = shared_ptr<boost::condition_variable>(new boost::condition_variable());
this->threads = _threads;
this->block_complete = 0;
this->block_submit = 0;
pool = shared_ptr<boost::asio::thread_pool>(new boost::asio::thread_pool(threads));
memory = new Context*[threads];
window = new Context*[threads];
partial = nullptr;
for (int i=0; i<threads; i++) {
memory[i] = new Context(this);
window[i] = nullptr;
}
SHA256_Init(&sha256);
}
DBXHash::~DBXHash() {
for (int i=0; i<threads; i++) {
delete memory[i];
memory[i] = nullptr;
}
delete[] memory; memory = nullptr;
delete[] window; window = nullptr;
}
void DBXHash::finish(byte* hash) {
Locker m(lock, signal);
if (partial != nullptr) submit(partial);
while (block_complete < block_submit) m.wait();
SHA256_Final(hash, &sha256);
}
Context* DBXHash::findContext(int state) {
for (int i=0; i<threads; i++) {
if (memory[i]->state == state) return memory[i];
}
return nullptr;
}
void DBXHash::submit(Context* c) {
assert(c->state == st_partial);
c->state = st_full;
c->block = block_submit++;
partial = nullptr;
boost::asio::post(*pool, boost::bind(&Context::operator(), c));
}
void DBXHash::update(byte* buffer, int64_t len) {
int64_t off = 0;
if (len == 0) return;
Locker m(lock, signal);
while (true) {
Context* c;
if (partial != nullptr) c = partial;
else {
while (true) {
c = findContext(st_free);
if (c != nullptr) break;
m.wait();
}
assert(c->state == st_free);
c->state = st_partial;
}
int64_t amount = std::min(BLOCK_SIZE-c->size, std::min(BLOCK_SIZE, len));
memcpy(c->data+c->size, buffer+off, amount);
c->size += amount; off += amount; len -= amount;
if (c->size == BLOCK_SIZE) submit(c);
else partial = c;
assert(len >= 0);
if (len == 0) break;
}
}
void DBXHash::process(std::istream& in, byte* hash, int64_t bufferSize) {
shared_ptr<byte> buffer((byte*) malloc(bufferSize), free);
while (true) {
in.clear();
if (!in.read((char*) buffer.get(), bufferSize) and !in.eof()) {
cerr << std::hex << in.fail() << " error reading the file" << endl;
}
int64_t read = in.gcount();
if (read == 0) break;
update(buffer.get(), read);
}
finish(hash);
}