eOn client
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
Bundling.cpp
Go to the documentation of this file.
1
/*
2
** This file is part of eOn.
3
**
4
** SPDX-License-Identifier: BSD-3-Clause
5
**
6
** Copyright (c) 2010--present, eOn Development Team
7
** All rights reserved.
8
**
9
** Repo:
10
** https://github.com/TheochemUI/eOn
11
*/
12
13
#include "
eon/Bundling.h
"
14
#include "
eon/EonLogger.h
"
15
16
#include <cctype>
17
#include <cstdio>
18
#include <cstdlib>
19
#include <cstring>
20
#include <filesystem>
21
#include <system_error>
22
#include <utility>
23
24
namespace
fs = std::filesystem;
25
26
namespace
eonc
{
27
28
int
getBundleSize
() {
29
int
num_bundle = -1;
30
31
for
(
const
auto
&entry : fs::directory_iterator(
"."
)) {
32
std::string name = entry.path().filename().string();
33
34
if
(name[0] ==
'.'
) {
35
continue
;
36
}
37
38
// If "config" is not in the filename
39
// then skip.
40
if
(name.find(
"config"
) == std::string::npos &&
41
name.find(
"ini"
) == std::string::npos) {
42
continue
;
43
}
44
45
// Find the last underscore
46
auto
upos = name.rfind(
'_'
);
47
if
(upos == std::string::npos) {
48
continue
;
49
}
50
51
// Find the last period
52
auto
dpos = name.rfind(
'.'
);
53
if
(dpos == std::string::npos || dpos <= upos) {
54
continue
;
55
}
56
57
std::string numstr = name.substr(upos + 1, dpos - upos - 1);
58
if
(!numstr.empty() &&
59
std::isdigit(
static_cast<
unsigned
char
>
(numstr[0]))) {
60
int
i = std::atoi(numstr.c_str()) + 1;
61
if
(i > num_bundle) {
62
num_bundle = i;
63
}
64
}
65
}
66
67
return
num_bundle;
68
}
69
70
int
strchrcount
(
const
char
*haystack,
char
needle) {
71
int
count = 0;
72
for
(
const
char
*ch = haystack; *ch !=
'\0'
; ch++) {
73
if
(*ch == needle) {
74
count++;
75
}
76
}
77
return
count;
78
}
79
80
std::vector<std::string>
unbundle
(
int
number) {
81
std::vector<std::string> filenames;
82
83
for
(
const
auto
&entry : fs::directory_iterator(
"."
)) {
84
std::string originalFilename = entry.path().filename().string();
85
86
if
(originalFilename[0] ==
'.'
) {
87
continue
;
88
}
89
90
int
numUnderscores =
strchrcount
(originalFilename.c_str(),
'_'
);
91
if
(numUnderscores < 1) {
92
continue
;
93
}
94
95
// Find the last underscore
96
auto
upos = originalFilename.rfind(
'_'
);
97
if
(upos == std::string::npos) {
98
continue
;
99
}
100
101
// Find the last period
102
auto
dpos = originalFilename.rfind(
'.'
);
103
if
(dpos == std::string::npos || dpos <= upos) {
104
continue
;
105
}
106
107
std::string numstr = originalFilename.substr(upos + 1, dpos - upos - 1);
108
if
(!numstr.empty() &&
109
std::isdigit(
static_cast<
unsigned
char
>
(numstr[0]))) {
110
int
bundleNumber = std::atoi(numstr.c_str());
111
if
(bundleNumber != number) {
112
continue
;
113
}
114
}
115
116
std::string baseName = originalFilename.substr(0, upos);
117
// Drop the "_<n>" token and keep everything after it, so a compound
118
// extension (".con.gz", ".con.zst") survives whichever side of the
119
// underscore it sits on.
120
size_t
extStart =
121
originalFilename.find_first_not_of(
"0123456789"
, upos + 1);
122
if
(extStart == std::string::npos) {
123
extStart = originalFilename.size();
124
}
125
std::string newFilename = baseName + originalFilename.substr(extStart);
126
127
try
{
128
fs::copy_file(originalFilename, newFilename,
129
fs::copy_options::overwrite_existing);
130
filenames.push_back(newFilename);
131
}
catch
(
const
fs::filesystem_error &e) {
132
EONC_LOG_ERROR
(
"unbundle: problem copying {} to {}: {}"
, originalFilename,
133
newFilename, e.what());
134
}
135
}
136
137
return
filenames;
138
}
139
140
void
deleteUnbundledFiles
(
const
std::vector<std::string> &unbundledFilenames) {
141
for
(
const
auto
&filename : unbundledFilenames) {
142
std::error_code ec;
143
fs::remove(filename, ec);
144
if
(ec) {
145
EONC_LOG_ERROR
(
"deleteUnbundledFiles: cannot remove {}: {}"
, filename,
146
ec.message());
147
}
148
}
149
}
150
151
namespace
{
152
157
std::pair<std::string, std::string>
158
splitBundleExtension(
const
std::string &name) {
159
const
size_t
pos = name.find_last_of(
'.'
);
160
if
(pos == std::string::npos) {
161
return
{name,
""
};
162
}
163
const
std::string tail = name.substr(pos);
164
if
(pos > 0 && (tail ==
".gz"
|| tail ==
".zst"
)) {
165
const
size_t
inner = name.find_last_of(
'.'
, pos - 1);
166
if
(inner != std::string::npos) {
167
return
{name.substr(0, inner), name.substr(inner)};
168
}
169
}
170
return
{name.substr(0, pos), tail};
171
}
172
173
}
// namespace
174
175
void
bundle
(
int
number,
const
std::vector<std::string> &filenames,
176
std::vector<std::string> *bundledFilenames) {
177
for
(
const
auto
&filename : filenames) {
178
const
auto
[baseName, ext] = splitBundleExtension(filename);
179
const
std::string newFilename =
180
baseName +
"_"
+ std::to_string(number) + ext;
181
182
try
{
183
fs::rename(filename, newFilename);
184
bundledFilenames->push_back(newFilename);
185
}
catch
(
const
fs::filesystem_error &e) {
186
EONC_LOG_ERROR
(
"bundle: cannot rename {} to {}: {}"
, filename,
187
newFilename, e.what());
188
}
189
}
190
}
191
192
}
// namespace eonc
Bundling.h
EonLogger.h
EONC_LOG_ERROR
#define EONC_LOG_ERROR(...)
Definition
EonLogger.h:262
eonc
RAII resource manager for the ARTn C library with global synchronization.
Definition
ARTnSaddleSearch.cpp:19
eonc::bundle
void bundle(int number, const std::vector< std::string > &filenames, std::vector< std::string > *bundledFilenames)
Definition
Bundling.cpp:175
eonc::deleteUnbundledFiles
void deleteUnbundledFiles(const std::vector< std::string > &unbundledFilenames)
Definition
Bundling.cpp:140
eonc::unbundle
std::vector< std::string > unbundle(int number)
Definition
Bundling.cpp:80
eonc::getBundleSize
int getBundleSize()
Definition
Bundling.cpp:28
eonc::strchrcount
int strchrcount(const char *haystack, char needle)
Definition
Bundling.cpp:70
client
Bundling.cpp
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf