137 lines
4.4 KiB
C++
137 lines
4.4 KiB
C++
#include "Internal.h"
|
|
#include <ConflictSet.h>
|
|
|
|
#include <chrono>
|
|
#include <cstring>
|
|
#include <fcntl.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <vector>
|
|
|
|
inline size_t getPageSize() {
|
|
static size_t kPageSize = sysconf(_SC_PAGESIZE);
|
|
return kPageSize;
|
|
}
|
|
|
|
/// Helper for rounding up to page size (or some other alignment)
|
|
constexpr inline size_t rightAlign(size_t offset, size_t alignment) {
|
|
return offset % alignment == 0 ? offset
|
|
: ((offset / alignment) + 1) * alignment;
|
|
}
|
|
|
|
using StringView = std::basic_string_view<uint8_t>;
|
|
|
|
inline StringView operator"" _v(const char *str, size_t size) {
|
|
return {reinterpret_cast<const uint8_t *>(str), size};
|
|
}
|
|
|
|
int main(int argc, const char **argv) {
|
|
|
|
ConflictSet cs{0};
|
|
ReferenceImpl ref{0};
|
|
|
|
for (int i = 1; i < argc; ++i) {
|
|
int fd = open(argv[i], O_RDONLY);
|
|
struct stat st;
|
|
if (fstat(fd, &st) == -1) {
|
|
int err = errno;
|
|
fprintf(stderr, "stat error %s - %s\n", argv[i], strerror(err));
|
|
fflush(stderr);
|
|
abort();
|
|
}
|
|
|
|
int64_t size = rightAlign(st.st_size, getPageSize());
|
|
const uint8_t *begin =
|
|
(uint8_t *)mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
madvise((void *)begin, size, MADV_SEQUENTIAL);
|
|
auto *const mapOriginal = begin;
|
|
const auto sizeOriginal = size;
|
|
|
|
StringView b;
|
|
StringView e;
|
|
int64_t v = 0;
|
|
std::vector<ConflictSet::WriteRange> writeRanges;
|
|
std::vector<ConflictSet::ReadRange> readRanges;
|
|
std::vector<ConflictSet::Result> results;
|
|
|
|
for (uint8_t *end = (uint8_t *)memchr(begin, '\n', size); end != nullptr;) {
|
|
StringView line{begin, static_cast<size_t>(end - begin)};
|
|
size -= end - begin + 1;
|
|
begin = end + 1;
|
|
end = (uint8_t *)memchr(begin, '\n', size);
|
|
|
|
if (line.starts_with("begin"_v)) {
|
|
b = line.substr("begin "_v.size(), line.size());
|
|
printf("b <- %.*s\n", int(b.size()), b.data());
|
|
} else if (line.starts_with("end"_v)) {
|
|
e = line.substr("end "_v.size(), line.size());
|
|
printf("e <- %.*s\n", int(e.size()), e.data());
|
|
} else if (line.starts_with("version"_v)) {
|
|
line = line.substr("version "_v.size(), line.size());
|
|
v = 0;
|
|
for (auto c : line) {
|
|
v = v * 10 + int(c) - int('0');
|
|
}
|
|
printf("v <- %" PRId64 "\n", v);
|
|
} else if (line.starts_with("pointread"_v)) {
|
|
printf("pointread\n");
|
|
ConflictSet::ReadRange r;
|
|
r.begin.p = b.data();
|
|
r.begin.len = b.size();
|
|
r.end.len = 0;
|
|
r.readVersion = v;
|
|
readRanges.push_back(r);
|
|
} else if (line.starts_with("pointwrite"_v)) {
|
|
printf("pointwrite\n");
|
|
ConflictSet::WriteRange w;
|
|
w.begin.p = b.data();
|
|
w.begin.len = b.size();
|
|
w.end.len = 0;
|
|
writeRanges.push_back(w);
|
|
} else if (line.starts_with("rangeread"_v)) {
|
|
printf("rangeread\n");
|
|
ConflictSet::ReadRange r;
|
|
r.begin.p = b.data();
|
|
r.begin.len = b.size();
|
|
r.end.p = e.data();
|
|
r.end.len = e.size();
|
|
r.readVersion = v;
|
|
readRanges.push_back(r);
|
|
} else if (line.starts_with("rangewrite"_v)) {
|
|
printf("rangewrite\n");
|
|
ConflictSet::WriteRange w;
|
|
w.begin.p = b.data();
|
|
w.begin.len = b.size();
|
|
w.end.p = e.data();
|
|
w.end.len = e.size();
|
|
writeRanges.push_back(w);
|
|
} else if (line.starts_with("check"_v)) {
|
|
printf("check\n");
|
|
Arena arena;
|
|
auto *expected = new (arena) ConflictSet::Result[readRanges.size()];
|
|
auto *actual = new (arena) ConflictSet::Result[readRanges.size()];
|
|
ref.check(readRanges.data(), expected, readRanges.size());
|
|
cs.check(readRanges.data(), actual, readRanges.size());
|
|
for (int i = 0; i < int(readRanges.size()); ++i) {
|
|
assert(expected[i] == actual[i]);
|
|
}
|
|
readRanges = {};
|
|
} else if (line.starts_with("addwrites"_v)) {
|
|
printf("addwrites\n");
|
|
cs.addWrites(writeRanges.data(), writeRanges.size(), v);
|
|
ref.addWrites(writeRanges.data(), writeRanges.size(), v);
|
|
writeRanges = {};
|
|
} else if (line.starts_with("setoldest"_v)) {
|
|
printf("setoldest\n");
|
|
cs.setOldestVersion(v);
|
|
ref.setOldestVersion(v);
|
|
} else {
|
|
printf("Unrecognized line: %.*s\n", int(line.size()), line.data());
|
|
}
|
|
}
|
|
munmap((void *)mapOriginal, sizeOriginal);
|
|
close(fd);
|
|
}
|
|
}
|