1
0
Fork 0

Logger, libguarded

This commit is contained in:
May B. 2020-08-01 00:11:08 +02:00
parent d53299ebc8
commit 21b95ba5fe
15 changed files with 543 additions and 50 deletions

View File

@ -44,6 +44,7 @@ set(INCLUDE_LIBS
"include/toml++"
"include/Remotery/lib"
"include/robin_hood"
"include/libguarded"
)
add_executable(univerxel "src/main.cpp" ${SOURCES} ${INCLUDE_SOURCES})

View File

@ -32,12 +32,9 @@
- [ ] sanitizer
- [ ] clang-tidy
- [ ] cmake
- https://github.com/microsoft/GSL/blob/master/include/gsl/pointers
- [ ] Server
- [ ] ZeroMQ
- [ ] Mutex guard
- [ ] Shared mutex
- [ ] Logger
- [x] Logger
## Rendering
- [x] Render triangle

View File

@ -0,0 +1,25 @@
Copyright (c) 2016, Ansel Sermersheim
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,198 @@
/***********************************************************************
*
* Copyright (c) 2015-2020 Ansel Sermersheim
*
* This file is part of CsLibGuarded.
*
* CsLibGuarded is free software, released under the BSD 2-Clause license.
* For license details refer to LICENSE provided with this project.
*
* CopperSpice is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* https://opensource.org/licenses/BSD-2-Clause
*
***********************************************************************/
#ifndef CSLIBGUARDED_PLAIN_GUARDED_H
#define CSLIBGUARDED_PLAIN_GUARDED_H
#include <memory>
#include <mutex>
namespace libguarded
{
/**
\headerfile cs_plain_guarded.h <CsLibGuarded/cs_plain_guarded.h>
This templated class wraps an object and allows only one thread at a
time to access the protected object.
This class will use std::mutex for the internal locking mechanism by
default. Other classes which are useful for the mutex type are
std::recursive_mutex, std::timed_mutex, and
std::recursive_timed_mutex.
The handle returned by the various lock methods is moveable but not
copyable.
*/
template <typename T, typename M = std::mutex>
class plain_guarded
{
private:
class deleter;
public:
using handle = std::unique_ptr<T, deleter>;
/**
Construct a guarded object. This constructor will accept any
number of parameters, all of which are forwarded to the
constructor of T.
*/
template <typename... Us>
plain_guarded(Us &&... data);
/**
Acquire a handle to the protected object. As a side effect, the
protected object will be locked from access by any other
thread. The lock will be automatically released when the handle
is destroyed.
*/
[[nodiscard]] handle lock();
/**
Attempt to acquire a handle to the protected object. Returns a
null handle if the object is already locked. As a side effect,
the protected object will be locked from access by any other
thread. The lock will be automatically released when the handle
is destroyed.
*/
[[nodiscard]] handle try_lock();
/**
Attempt to acquire a handle to the protected object. As a side
effect, the protected object will be locked from access by any
other thread. The lock will be automatically released when the
handle is destroyed.
Returns a null handle if the object is already locked, and does
not become available for locking before the time duration has
elapsed.
Calling this method requires that the underlying mutex type M
supports the try_lock_for method. This is not true if M is the
default std::mutex.
*/
template <class Duration>
[[nodiscard]] handle try_lock_for(const Duration &duration);
/**
Attempt to acquire a handle to the protected object. As a side
effect, the protected object will be locked from access by any other
thread. The lock will be automatically released when the handle is
destroyed.
Returns a null handle if the object is already locked, and does not
become available for locking before reaching the specified timepoint.
Calling this method requires that the underlying mutex type M
supports the try_lock_until method. This is not true if M is the
default std::mutex.
*/
template <class TimePoint>
[[nodiscard]] handle try_lock_until(const TimePoint &timepoint);
private:
T m_obj;
M m_mutex;
};
template <typename T, typename M>
class plain_guarded<T, M>::deleter
{
public:
using pointer = T *;
deleter(std::unique_lock<M> lock);
void operator()(T *ptr);
private:
std::unique_lock<M> m_lock;
};
template <typename T, typename M>
plain_guarded<T, M>::deleter::deleter(std::unique_lock<M> lock)
: m_lock(std::move(lock))
{
}
template <typename T, typename M>
void plain_guarded<T, M>::deleter::operator()(T *)
{
if (m_lock.owns_lock()) {
m_lock.unlock();
}
}
template <typename T, typename M>
template <typename... Us>
plain_guarded<T, M>::plain_guarded(Us &&... data)
: m_obj(std::forward<Us>(data)...)
{
}
template <typename T, typename M>
auto plain_guarded<T, M>::lock() -> handle
{
std::unique_lock<M> lock(m_mutex);
return handle(&m_obj, deleter(std::move(lock)));
}
template <typename T, typename M>
auto plain_guarded<T, M>::try_lock() -> handle
{
std::unique_lock<M> lock(m_mutex, std::try_to_lock);
if (lock.owns_lock()) {
return handle(&m_obj, deleter(std::move(lock)));
} else {
return handle(nullptr, deleter(std::move(lock)));
}
}
template <typename T, typename M>
template <typename Duration>
auto plain_guarded<T, M>::try_lock_for(const Duration &d) -> handle
{
std::unique_lock<M> lock(m_mutex, d);
if (lock.owns_lock()) {
return handle(&m_obj, deleter(std::move(lock)));
} else {
return handle(nullptr, deleter(std::move(lock)));
}
}
template <typename T, typename M>
template <typename TimePoint>
auto plain_guarded<T, M>::try_lock_until(const TimePoint &tp) -> handle
{
std::unique_lock<M> lock(m_mutex, tp);
if (lock.owns_lock()) {
return handle(&m_obj, deleter(std::move(lock)));
} else {
return handle(nullptr, deleter(std::move(lock)));
}
}
template <typename T, typename M = std::mutex>
using guarded [[deprecated("renamed to plain_guarded")]] = plain_guarded<T, M>;
} // namespace libguarded
#endif

View File

@ -0,0 +1,234 @@
/***********************************************************************
*
* Copyright (c) 2015-2020 Ansel Sermersheim
*
* This file is part of CsLibGuarded.
*
* CsLibGuarded is free software, released under the BSD 2-Clause license.
* For license details refer to LICENSE provided with this project.
*
* CopperSpice is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* https://opensource.org/licenses/BSD-2-Clause
*
***********************************************************************/
#ifndef CSLIBGUARDED_SHARED_GUARDED_H
#define CSLIBGUARDED_SHARED_GUARDED_H
#include <memory>
#include <shared_mutex>
namespace libguarded
{
/**
\headerfile cs_shared_guarded.h <CsLibGuarded/cs_shared_guarded.h>
This templated class wraps an object and allows only one thread at
a time to modify the protected object.
This class will use std::shared_timed_mutex for the internal
locking mechanism by default. In C++17 the std::shared_mutex class
is also available.
The handle returned by the various lock methods is moveable but not
copyable.
*/
template <typename T, typename M = std::shared_timed_mutex, typename L = std::shared_lock<M>>
class shared_guarded
{
private:
class deleter;
class shared_deleter;
public:
using handle = std::unique_ptr<T, deleter>;
using shared_handle = std::unique_ptr<const T, shared_deleter>;
template <typename... Us>
shared_guarded(Us &&... data);
// exclusive access
[[nodiscard]] handle lock();
[[nodiscard]] handle try_lock();
template <class Duration>
[[nodiscard]] handle try_lock_for(const Duration &duration);
template <class TimePoint>
[[nodiscard]] handle try_lock_until(const TimePoint &timepoint);
// shared access, note "shared" in method names
[[nodiscard]] shared_handle lock_shared() const;
[[nodiscard]] shared_handle try_lock_shared() const;
template <class Duration>
[[nodiscard]] shared_handle try_lock_shared_for(const Duration &duration) const;
template <class TimePoint>
[[nodiscard]] shared_handle try_lock_shared_until(const TimePoint &timepoint) const;
private:
T m_obj;
mutable M m_mutex;
};
template <typename T, typename M, typename L>
class shared_guarded<T, M, L>::deleter
{
public:
using pointer = T *;
deleter(std::unique_lock<M> lock);
void operator()(T *ptr);
private:
std::unique_lock<M> m_lock;
};
template <typename T, typename M, typename L>
shared_guarded<T, M, L>::deleter::deleter(std::unique_lock<M> lock)
: m_lock(std::move(lock))
{
}
template <typename T, typename M, typename L>
void shared_guarded<T, M, L>::deleter::operator()(T *)
{
if (m_lock.owns_lock()) {
m_lock.unlock();
}
}
template <typename T, typename M, typename L>
class shared_guarded<T, M, L>::shared_deleter
{
public:
using pointer = const T *;
shared_deleter(L lock);
void operator()(const T *ptr);
private:
L m_lock;
};
template <typename T, typename M, typename L>
shared_guarded<T, M, L>::shared_deleter::shared_deleter(L lock)
: m_lock(std::move(lock))
{
}
template <typename T, typename M, typename L>
void shared_guarded<T, M, L>::shared_deleter::operator()(const T *)
{
if (m_lock.owns_lock()) {
m_lock.unlock();
}
}
template <typename T, typename M, typename L>
template <typename... Us>
shared_guarded<T, M, L>::shared_guarded(Us &&... data)
: m_obj(std::forward<Us>(data)...)
{
}
template <typename T, typename M, typename L>
auto shared_guarded<T, M, L>::lock() -> handle
{
std::unique_lock<M> lock(m_mutex);
return handle(&m_obj, deleter(std::move(lock)));
}
template <typename T, typename M, typename L>
auto shared_guarded<T, M, L>::try_lock() -> handle
{
std::unique_lock<M> lock(m_mutex, std::try_to_lock);
if (lock.owns_lock()) {
return handle(&m_obj, deleter(std::move(lock)));
} else {
return handle(nullptr, deleter(std::move(lock)));
}
}
template <typename T, typename M, typename L>
template <typename Duration>
auto shared_guarded<T, M, L>::try_lock_for(const Duration &duration) -> handle
{
std::unique_lock<M> lock(m_mutex, duration);
if (lock.owns_lock()) {
return handle(&m_obj, deleter(std::move(lock)));
} else {
return handle(nullptr, deleter(std::move(lock)));
}
}
template <typename T, typename M, typename L>
template <typename TimePoint>
auto shared_guarded<T, M, L>::try_lock_until(const TimePoint &timepoint) -> handle
{
std::unique_lock<M> lock(m_mutex, timepoint);
if (lock.owns_lock()) {
return handle(&m_obj, deleter(std::move(lock)));
} else {
return handle(nullptr, deleter(std::move(lock)));
}
}
template <typename T, typename M, typename L>
auto shared_guarded<T, M, L>::lock_shared() const -> shared_handle
{
L lock(m_mutex);
return shared_handle(&m_obj, shared_deleter(std::move(lock)));
}
template <typename T, typename M, typename L>
auto shared_guarded<T, M, L>::try_lock_shared() const -> shared_handle
{
L lock(m_mutex, std::try_to_lock);
if (lock.owns_lock()) {
return shared_handle(&m_obj, shared_deleter(std::move(lock)));
} else {
return shared_handle(nullptr, shared_deleter(std::move(lock)));
}
}
template <typename T, typename M, typename L>
template <typename Duration>
auto shared_guarded<T, M, L>::try_lock_shared_for(const Duration &d) const -> shared_handle
{
L lock(m_mutex, d);
if (lock.owns_lock()) {
return shared_handle(&m_obj, shared_deleter(std::move(lock)));
} else {
return shared_handle(nullptr, shared_deleter(std::move(lock)));
}
}
template <typename T, typename M, typename L>
template <typename TimePoint>
auto shared_guarded<T, M, L>::try_lock_shared_until(const TimePoint &tp) const -> shared_handle
{
L lock(m_mutex, tp);
if (lock.owns_lock()) {
return shared_handle(&m_obj, shared_deleter(std::move(lock)));
} else {
return shared_handle(nullptr, shared_deleter(std::move(lock)));
}
}
} // namespace libguarded
#endif

11
src/data/colors.h Normal file
View File

@ -0,0 +1,11 @@
#define GREY "\033[0;90m"
#define GREEN "\033[0;32m"
#define BROWN "\033[0;33m"
#define BLUE "\033[0;34m"
#define RED "\033[1;31m"
#define YELLOW "\033[1;33m"
#define BOLD "\033[1;1m"
#define BLUE_BOLD "\033[1;34m"
#define END_COLOR "\033[0m"
#define UNDERLINE "\e[4m"
#define END_STYLE "\e[0m"

11
src/data/logger.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "logger.hpp"
#include <chrono>
#include <ctime>
namespace logger {
std::_Put_time<char> now() {
const auto tp = std::chrono::system_clock::now();
const auto timet = std::chrono::system_clock::to_time_t(tp);
return std::put_time(std::localtime(&timet), "%Y-%m-%d %X");
}
}

16
src/data/logger.hpp Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include "colors.h"
#include <iostream>
#include <iomanip>
#define _OUT(expr) {std::ostringstream oss; oss << expr << std::endl; std::cout << oss.str();}
#define LOG(expr) _OUT("[" << logger::now() << "] " << expr)
#define LOG_E(expr) _OUT("[" << RED << logger::now() << END_COLOR << "] " << expr)
#define LOG_W(expr) _OUT("[" << YELLOW << logger::now() << END_COLOR << "] " << expr)
#define LOG_I(expr) _OUT("[" << GREEN << logger::now() << END_COLOR << "] " << expr)
#define LOG_D(expr) _OUT("[" << GREY << logger::now() << END_COLOR << "] " << expr)
namespace logger {
std::_Put_time<char> now();
}

View File

@ -24,6 +24,7 @@
/// Entry point
int main(int, char *[]){
LOG("Univerxel");
options options;
state state;
reports reports;
@ -77,7 +78,7 @@ int main(int, char *[]){
rmt_CreateGlobalInstance(&rmt);
rmt_BindOpenGL();
#if RMT_ENABLED
std::cout << "Profiling !" << std::endl;
LOG("Profiling !");
#endif
world::Universe world = world::Universe(options.world);

View File

@ -1,6 +1,7 @@
#include "ShortIndexed.hpp"
#include "vboindexer.hpp"
#include "../../data/logger.hpp"
using namespace buffer;
@ -95,7 +96,7 @@ void ShortIndexed::setData(const ShortIndexed::Data& data) {
IndexSize = data.indices.size();
if(IndexSize != data.indices.size()) {
std::cout << "ShortBuffer overflow: " << data.indices.size() << std::endl;
LOG_E("ShortBuffer overflow: " << data.indices.size());
}
setIndicies(IndexSize * sizeof(GLushort), &data.indices[0]);
setVertices(data.vertices.size() * sizeof(glm::vec3), &data.vertices[0]);

View File

@ -8,7 +8,7 @@
using namespace world;
Universe::Universe(const Universe::options &options): generator(42), regionDict("content/zstd.dict"), contouring(std::make_shared<contouring::Dummy>()) {
Universe::Universe(const Universe::options &options): generator(42), dicts("content/zstd.dict"), contouring(std::make_shared<contouring::Dummy>()) {
setOptions(options);
folderPath = options.folderPath;
struct vec_istream: std::streambuf {
@ -22,7 +22,7 @@ Universe::Universe(const Universe::options &options): generator(42), regionDict(
// Load workers
for (size_t i = 0; i < 4; i++) {
loadWorkers.emplace_back([&] {
const auto ctx = regionDict.make_reader();
const auto ctx = dicts.make_reader();
while (running) {
chunk_pos pos;
loadQueue.wait();
@ -50,7 +50,7 @@ Universe::Universe(const Universe::options &options): generator(42), regionDict(
// Save workers
for (size_t i = 0; i < 2; i++) {
saveWorkers.emplace_back([&] {
const auto ctx = regionDict.make_writer();
const auto ctx = dicts.make_writer();
while (running) {
robin_hood::pair<chunk_pos, std::shared_ptr<Chunk>> task;
saveQueue.wait();
@ -100,16 +100,16 @@ Universe::~Universe() {
}
std::shared_ptr<Region> Universe::getRegion(const region_pos& pos) {
std::shared_lock lock(regionMutex);
const auto it = regionCache.find(pos);
if(it == regionCache.end()) {
lock.unlock();
const auto reg = std::make_shared<Region>(folderPath, pos);
std::unique_lock u_lock(regionMutex);
return regionCache.insert({pos, reg}).first->second;
} else {
return it->second;
{ // Found
const auto shared = regions.lock_shared();
const auto it = shared->find(pos);
if(it != shared->end())
return it->second;
}
// Reading
const auto reg = std::make_shared<Region>(folderPath, pos);
const auto unique = regions.lock();
return unique->insert({pos, reg}).first->second;
}
void Universe::update(const camera_pos& pos, Universe::report& rep) {
@ -174,18 +174,17 @@ void Universe::update(const camera_pos& pos, Universe::report& rep) {
{
rmt_ScopedCPUSample(Region, 0);
std::unique_lock lock(regionMutex);
const auto unique = regions.lock(); // MAYBE: shared then unique
rep.region_count.push(unique->size());
const auto me = glm::divide(last_pos, glm::ivec3(REGION_LENGTH));
for (auto it = regionCache.begin(); it != regionCache.end();) {
for (auto it = unique->begin(); it != unique->end(); it++) {
if (glm::length2(it->first - me) > keepDistance) {
std::cout << "rem" << std::endl;
it = regionCache.erase(it);
} else {
it++;
LOG_D("Remove region");
unique->erase(it);
break; //NOTE: save one max per frame
}
}
}
rep.region_count.push(regionCache.size());
}
void Universe::setOptions(const Universe::options& options) {
loadDistance = options.loadDistance;

View File

@ -1,9 +1,9 @@
#pragma once
#include <string>
#include <memory>
#include <thread>
#include <shared_mutex>
#include <shared_mutex_guarded.h>
using namespace libguarded;
#include "../data/math.hpp"
#include "../data/safe_queue.hpp"
#include "../data/safe_priority_queue.hpp"
@ -98,9 +98,8 @@ namespace world {
int keepDistance;
std::string folderPath;
std::shared_mutex regionMutex; //MAYBE: shared_guard
robin_hood::unordered_map<region_pos, std::shared_ptr<Region>> regionCache;
dict_set regionDict;
shared_guarded<robin_hood::unordered_map<region_pos, std::shared_ptr<Region>>> regions;
dict_set dicts;
std::shared_ptr<Region> getRegion(const region_pos &);
/// Contouring worker

View File

@ -45,14 +45,14 @@ void FileRegion::load() {
// Ignore content
if(!index.insert({pos, std::make_pair(size, file.tellg())}).second) {
std::cout << "Duplicated chunk: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << std::endl;
LOG_E("Duplicated chunk: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z);
}
file.ignore(size);
file.peek();
}
if(file.bad()) {
std::cout << "region corrupted read " << path << std::endl;
LOG_E("region corrupted read " << path);
}
assert(index.size() == chunkCount);
@ -73,10 +73,10 @@ bool FileRegion::read(const region_chunk_pos& pos, const read_ctx& ctx, data& ou
out.resize(maxSize);
const auto actualSize = ZSTD_decompress_usingDDict(ctx.ctx, out.data(), out.size(), in->data(), in->size(), ctx.dict);
if(ZSTD_isError(actualSize)) {
std::cout << "Corrupted region chunk: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << " "
<< ZSTD_getErrorName(actualSize) << std::endl;
LOG_E("Corrupted region chunk: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << " "
<< ZSTD_getErrorName(actualSize));
#ifdef REMOVE_CORRUPTED
std::cout << "Removing" << std::endl;
LOG_W("Removing");
index.erase(it);
lock.unlock();
save(std::nullopt);
@ -93,8 +93,8 @@ void FileRegion::write(const region_chunk_pos& pos, const write_ctx& ctx, const
const auto actualSize = ZSTD_compress_usingCDict(ctx.ctx, buffer->data(), buffer->capacity(), in.data(), in.size(), ctx.dict);
if (ZSTD_isError(actualSize)) {
std::cout << "Corrupted chunk save: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << " "
<< ZSTD_getErrorName(actualSize) << std::endl;
LOG_E("Corrupted chunk save: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << " "
<< ZSTD_getErrorName(actualSize));
return;
}
buffer->resize(actualSize);
@ -108,7 +108,7 @@ void FileRegion::save(std::optional<std::pair<region_chunk_pos, std::unique_ptr<
std::ofstream tmpFile(tmpPath, std::ios::out | std::ios::binary);
if (!tmpFile.good()) {
std::cout << "Corrupted region path: " << tmpPath << std::endl;
LOG_E("Corrupted region path: " << tmpPath);
return;
}
@ -165,7 +165,7 @@ void FileRegion::save(std::optional<std::pair<region_chunk_pos, std::unique_ptr<
}
if (!tmpFile.good()) {
std::cout << "region corrupted write " << tmpPath << std::endl;
LOG_E("Region corrupted write " << tmpPath);
tmpFile.close();
return;
}

View File

@ -57,13 +57,13 @@ void MemoryRegion::load() {
data->resize(size);
file.read(data->data(), data->size());
if(!content.insert({pos, data}).second) {
std::cout << "Duplicated chunk: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << std::endl;
LOG_E("Duplicated chunk: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z);
}
file.peek();
}
if(file.bad()) {
std::cout << "region corrupted read " << path << std::endl;
LOG_E("Region corrupted read " << path);
}
assert(content.size() == chunkCount);
file.close();
@ -81,10 +81,10 @@ bool MemoryRegion::read(const region_chunk_pos& pos, const read_ctx& ctx, data&
out.resize(maxSize);
const auto actualSize = ZSTD_decompress_usingDDict(ctx.ctx, out.data(), out.size(), in->data(), in->size(), ctx.dict);
if(ZSTD_isError(actualSize)) {
std::cout << "Corrupted region chunk: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << " "
<< ZSTD_getErrorName(actualSize) << std::endl;
LOG_E("Corrupted region chunk: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << " "
<< ZSTD_getErrorName(actualSize));
#ifdef REMOVE_CORRUPTED
std::cout << "Removing" << std::endl;
LOG_W("Removing");
lock.unlock();
{
std::unique_lock ulock(mutex);
@ -104,8 +104,8 @@ void MemoryRegion::write(const region_chunk_pos& pos, const write_ctx& ctx, cons
const auto actualSize = ZSTD_compress_usingCDict(ctx.ctx, buffer->data(), buffer->capacity(), in.data(), in.size(), ctx.dict);
if (ZSTD_isError(actualSize)) {
std::cout << "Corrupted chunk save: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << " "
<< ZSTD_getErrorName(actualSize) << std::endl;
LOG_E("Corrupted chunk save: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << " "
<< ZSTD_getErrorName(actualSize));
return;
}
buffer->resize(actualSize);
@ -134,7 +134,7 @@ void MemoryRegion::save(bool force) {
std::ofstream file(path, std::ios::out | std::ios::binary);
if (!file.good()) {
std::cout << "Corrupted region path: " << path << std::endl;
LOG_E("Corrupted region path: " << path);
return;
}
@ -169,7 +169,7 @@ void MemoryRegion::save(bool force) {
}
if (!file.good()) {
std::cout << "region corrupted write " << path << std::endl;
LOG_E("Region corrupted write " << path);
file.close();
return;
}

View File

@ -1,10 +1,10 @@
#pragma once
#include <zstd.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <cassert>
#include "../../data/logger.hpp"
namespace world {
struct read_ctx {
@ -27,7 +27,7 @@ namespace world {
dict_set(const std::string& path) {
std::ifstream is(path, std::ios::in | std::ios::binary | std::ios::ate);
if(!is.good()) {
std::cout << "missing dict " << path << std::endl;
LOG_E("Missing dict " << path);
exit(1);
}
const auto end = is.tellg();