forked from defuse/crackstation-hashdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsortidx.cpp
123 lines (98 loc) · 2.94 KB
/
sortidx.cpp
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "sortidx.h"
std::atomic<size_t> limit;
void sortIDX( const std::string & idxFile, size_t cacheByteSize, bool quiet ) {
ProgressBar progressBar;
FileArray fileArray( idxFile, cacheByteSize / FileArray::IndexEntry::indexSize, quiet ? NULL : &progressBar, false );
const size_t localLimit = fileArray.getSize() - 1;
limit = localLimit;
const size_t heapifyLimit = getParent( localLimit );
std::thread sorterThread;
if ( !quiet ) {
progressBar.init( {
{ "Sorting Index (Loading Cache)...", fileArray.getCacheSize() / 15 },
{ "Sorting Index (Creating Heap)...", heapifyLimit / 5 },
{ "Sorting Index (Sorting Heap)...", fileArray.getSize() },
{ "Sorting Index (Saving Cache)...", fileArray.getCacheSize() / 15 },
} );
progressBar.start();
}
fileArray.loadCacheFromFile();
heapifyIDX( fileArray, progressBar, heapifyLimit );
sortIDXHeap( fileArray, progressBar, localLimit );
fileArray.writeCacheToFile();
// Close the ProgressBar through RAII
}
void heapifyIDX( FileArray & fileArray, ProgressBar & progressBar, size_t heapifyLimit ) {
FileArray::IndexEntry top;
size_t posTop;
for ( size_t pos = 0; pos <= heapifyLimit; ) {
posTop = heapifyLimit - pos;
fileArray.readEntry( top, posTop );
orderHeap( fileArray, top, posTop );
progressBar.updateProgress( 1, ++pos, heapifyLimit + 1 );
}
}
void sortIDXHeap( FileArray & fileArray, ProgressBar & progressBar, size_t numDataSets ) {
FileArray::IndexEntry last;
FileArray::IndexEntry top;
size_t posLast;
size_t posTop;
for ( size_t pos = 0; pos < numDataSets; ) {
posLast = numDataSets - pos;
posTop = 0;
limit = posLast - 1;
fileArray.readEntry( last, posTop );
fileArray.readEntry( top, posLast );
fileArray.writeEntry( last, posLast );
orderHeap( fileArray, top, posTop );
progressBar.updateProgress( 2, ++pos, numDataSets );
}
}
bool isInHeap( size_t pos ) {
return pos <= limit;
}
void orderHeap( FileArray & fileArray, FileArray::IndexEntry &top, size_t posTop ) {
static FileArray::IndexEntry left;
static FileArray::IndexEntry right;
static size_t posLeft;
static size_t posRight;
static bool swapped;
do {
posLeft = getLeft( posTop );
posRight = getRight( posTop );
if ( isInHeap( posLeft ) ) {
fileArray.readEntry( left, posLeft );
if ( isInHeap( posRight ) ) {
fileArray.readEntry( right, posRight );
if ( left < right ) {
if ( top < right ) {
fileArray.writeEntry( right, posTop );
posTop = posRight;
swapped = true;
} else {
swapped = false;
}
} else {
if ( top < left ) {
fileArray.writeEntry( left, posTop );
posTop = posLeft;
swapped = true;
} else {
swapped = false;
}
}
} else {
if ( top < left ) {
fileArray.writeEntry( left, posTop );
posTop = posLeft;
swapped = true;
} else {
swapped = false;
}
}
} else {
swapped = false;
}
} while ( swapped );
fileArray.writeEntry( top, posTop );
}