Use 'M' or 'G' suffix for --memory option
This commit is contained in:
parent
771394aa9d
commit
67be4cbf7b
60
sortbin.cpp
60
sortbin.cpp
|
@ -1606,6 +1606,8 @@ void sortbin(
|
||||||
const std::string& output_name,
|
const std::string& output_name,
|
||||||
const SortContext& ctx)
|
const SortContext& ctx)
|
||||||
{
|
{
|
||||||
|
log(ctx, "using memory_size = %" PRIu64 " bytes\n", ctx.memory_size);
|
||||||
|
|
||||||
// We want file I/O to occur on 4096-byte boundaries.
|
// We want file I/O to occur on 4096-byte boundaries.
|
||||||
// To ensure this, we want to do I/O on multiples of 4096 records.
|
// To ensure this, we want to do I/O on multiples of 4096 records.
|
||||||
// To ensure this is possible, we need room for ~ 32k records per branch.
|
// To ensure this is possible, we need room for ~ 32k records per branch.
|
||||||
|
@ -1717,6 +1719,48 @@ std::string get_default_tmpdir(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a memory size specification.
|
||||||
|
*
|
||||||
|
* Memory size must be specified as an integer with suffix "M" or "G".
|
||||||
|
*
|
||||||
|
* @return specfified memory size in bytes, or 0 for an invalid size
|
||||||
|
*/
|
||||||
|
uint64_t parse_memory_size(const char *argstr)
|
||||||
|
{
|
||||||
|
char *endptr;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
long long value = strtoll(argstr, &endptr, 10);
|
||||||
|
if (endptr == argstr
|
||||||
|
|| (endptr[0] != 'G' && endptr[0] != 'M') || endptr[1] != '\0') {
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR: Invalid memory size."
|
||||||
|
" Specify e.g. '--memory=800M' or '--memory=4G'.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value <= 0 || errno != 0) {
|
||||||
|
fprintf(stderr, "ERROR: Invalid memory size\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t factor;
|
||||||
|
if (endptr[0] == 'G') {
|
||||||
|
factor = 1024 * 1024 * 1024;
|
||||||
|
} else {
|
||||||
|
factor = 1024 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((unsigned long long)value > UINT64_MAX / factor) {
|
||||||
|
fprintf(stderr, "ERROR: Invalid memory size\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value * factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void usage()
|
void usage()
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -1729,7 +1773,8 @@ void usage()
|
||||||
"\n"
|
"\n"
|
||||||
" -s, --size=N specify record size of N bytes (required)\n"
|
" -s, --size=N specify record size of N bytes (required)\n"
|
||||||
" -u, --unique eliminate duplicates after sorting\n"
|
" -u, --unique eliminate duplicates after sorting\n"
|
||||||
" --memory=M use at most M MByte RAM (default: %d)\n"
|
" --memory=<n>M use at most <n> MiByte RAM (default: %d)\n"
|
||||||
|
" --memory=<n>G use at most <n> GiByte RAM\n"
|
||||||
" --branch=B merge at most B arrays in one step (default: %d)\n"
|
" --branch=B merge at most B arrays in one step (default: %d)\n"
|
||||||
" --temporary-directory=DIR write temporary file to the specified\n"
|
" --temporary-directory=DIR write temporary file to the specified\n"
|
||||||
" directory (default: $TMPDIR)\n"
|
" directory (default: $TMPDIR)\n"
|
||||||
|
@ -1761,7 +1806,7 @@ int main(int argc, char **argv)
|
||||||
bool flag_unique = false;
|
bool flag_unique = false;
|
||||||
bool flag_verbose = false;
|
bool flag_verbose = false;
|
||||||
int record_size = 0;
|
int record_size = 0;
|
||||||
int memory_size = DEFAULT_MEMORY_SIZE_MBYTE;
|
uint64_t memory_size = uint64_t(DEFAULT_MEMORY_SIZE_MBYTE) * 1024 * 1024;
|
||||||
int branch_factor = DEFAULT_BRANCH_FACTOR;
|
int branch_factor = DEFAULT_BRANCH_FACTOR;
|
||||||
std::string tempdir = get_default_tmpdir();
|
std::string tempdir = get_default_tmpdir();
|
||||||
int opt;
|
int opt;
|
||||||
|
@ -1780,9 +1825,8 @@ int main(int argc, char **argv)
|
||||||
flag_unique = true;
|
flag_unique = true;
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
memory_size = atoi(optarg);
|
memory_size = parse_memory_size(optarg);
|
||||||
if (memory_size <= 0) {
|
if (memory_size == 0) {
|
||||||
fprintf(stderr, "ERROR: Invalid memory size\n");
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1828,10 +1872,10 @@ int main(int argc, char **argv)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((unsigned int)memory_size >= SIZE_MAX / 1024 / 1024) {
|
if (memory_size >= SIZE_MAX) {
|
||||||
fprintf(
|
fprintf(
|
||||||
stderr,
|
stderr,
|
||||||
"ERROR: This system can allocate at most %zu MB memory\n",
|
"ERROR: This system supports at most %zu MB memory\n",
|
||||||
SIZE_MAX / 1024 / 1024 - 1);
|
SIZE_MAX / 1024 / 1024 - 1);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -1841,7 +1885,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
SortContext ctx;
|
SortContext ctx;
|
||||||
ctx.record_size = record_size;
|
ctx.record_size = record_size;
|
||||||
ctx.memory_size = size_t(memory_size) * 1024 * 1024;
|
ctx.memory_size = memory_size;
|
||||||
ctx.branch_factor = branch_factor;
|
ctx.branch_factor = branch_factor;
|
||||||
ctx.flag_unique = flag_unique;
|
ctx.flag_unique = flag_unique;
|
||||||
ctx.flag_verbose = flag_verbose;
|
ctx.flag_verbose = flag_verbose;
|
||||||
|
|
Loading…
Reference in New Issue