Compare commits
36 Commits
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef _ERROR_H
|
||||||
|
#define _ERROR_H
|
||||||
|
|
||||||
|
#ifndef $PASTE
|
||||||
|
# define $_PASTE(x,y) x ## y
|
||||||
|
# define $PASTE(x,y) $_PASTE(x,y)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline bool is_noexcept=
|
||||||
|
#if __cpp_exceptions
|
||||||
|
#define EXCEPT 1
|
||||||
|
//#define try try
|
||||||
|
//#define catch(...) catch(__VA_ARGS__)
|
||||||
|
false
|
||||||
|
#else
|
||||||
|
#define EXCEPT 0
|
||||||
|
#define NOEXCEPT
|
||||||
|
//#define catch(...) __try {} catch(__VA_ARGS__)
|
||||||
|
//#define try if constexpr(!is_noexcept)
|
||||||
|
//#define throw (void)0
|
||||||
|
true
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _ERROR_H */
|
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef _FSVEC_H
|
||||||
|
#define _FSVEC_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#define restrict __restrict__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// A simple file-backed back inserter
|
||||||
|
typedef struct {
|
||||||
|
FILE* backing;
|
||||||
|
size_t len;
|
||||||
|
} fvec_t;
|
||||||
|
|
||||||
|
int fvec_new(fvec_t* restrict obj, const char* path);
|
||||||
|
void fvec_close(fvec_t* restrict obj);
|
||||||
|
|
||||||
|
int fvec_pop_end(fvec_t* restrict obj, size_t sz);
|
||||||
|
void fvec_push_whole_buffer(fvec_t* restrict obj, const void* _buffer, size_t sz);
|
||||||
|
int fvec_get_whole_buffer(const fvec_t* restrict obj, void* _buffer, size_t _sz);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#undef restrict
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _FSVEC_H */
|
@ -0,0 +1,324 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <map.h>
|
||||||
|
#include <tempfile.hpp>
|
||||||
|
#include <panic.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <shuffle3.h>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct i_back_inserter
|
||||||
|
{
|
||||||
|
virtual void push_back(T&& value) =0;
|
||||||
|
virtual void pop_back() =0;
|
||||||
|
virtual const T& back() const =0;
|
||||||
|
virtual T& back() =0;
|
||||||
|
virtual const std::size_t size() const =0;
|
||||||
|
|
||||||
|
inline bool is_empty() const { return size()==0; }
|
||||||
|
|
||||||
|
virtual inline ~i_back_inserter() =default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct i_shunt
|
||||||
|
{
|
||||||
|
virtual bool is_full() const =0;
|
||||||
|
virtual inline ~i_shunt() =default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct file_back_buffer
|
||||||
|
{
|
||||||
|
const static constexpr std::size_t DEFAULT_CAP = 1024;
|
||||||
|
typedef std::uint8_t byte;
|
||||||
|
|
||||||
|
file_back_buffer();
|
||||||
|
file_back_buffer(std::size_t cap);
|
||||||
|
file_back_buffer(const file_back_buffer& c) = delete;
|
||||||
|
file_back_buffer(file_back_buffer&& m);
|
||||||
|
|
||||||
|
void push_buf(byte* buf, std::size_t len);
|
||||||
|
bool back(byte* buf, std::size_t len) const;
|
||||||
|
bool pop_n(std::size_t len);
|
||||||
|
|
||||||
|
~file_back_buffer();
|
||||||
|
private:
|
||||||
|
struct impl;
|
||||||
|
std::unique_ptr<impl> inner;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template<typename T>
|
||||||
|
inline const T* _die_if_null(const T* input, const char* msg)
|
||||||
|
{
|
||||||
|
if(!input) panic(msg);
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline T* _die_if_null(T* input, const char* msg)
|
||||||
|
{
|
||||||
|
if(!input) panic(msg);
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct file_vector : public i_back_inserter<T>
|
||||||
|
{
|
||||||
|
inline file_vector() : file_vector(file_back_buffer::DEFAULT_CAP){}
|
||||||
|
inline file_vector(std::size_t cap) : inserter(file_back_buffer(cap)), len(0), current_back(std::vector<unsigned char>(sizeof(T))) {current_back.resize(sizeof(T));}
|
||||||
|
inline file_vector(const file_vector<T>& c) = delete;
|
||||||
|
inline file_vector(file_vector<T>&& m) : inserter(std::move(m.inserter)), len(m.len), current_back(std::move(m.current_back)){}
|
||||||
|
|
||||||
|
inline void push_back(T&& value) override
|
||||||
|
{
|
||||||
|
inserter.push_buf((file_back_buffer::byte*)&value, sizeof(T));
|
||||||
|
len += 1;
|
||||||
|
}
|
||||||
|
inline T& back() override
|
||||||
|
{
|
||||||
|
if(!len) panic("back() called on empty file_vector");
|
||||||
|
if(!inserter.back(¤t_back[0], sizeof(T))) panic("back() failed");
|
||||||
|
return *_die_if_null((T*)¤t_back[0], "file_vector::back() returned null pointer");
|
||||||
|
}
|
||||||
|
inline const T& back() const override
|
||||||
|
{
|
||||||
|
if(!len) panic("back() called on empty file_vector");
|
||||||
|
if(!inserter.back(¤t_back[0], sizeof(T))) panic("back() failed");
|
||||||
|
return *_die_if_null((const T*)¤t_back[0], "file_vector::back() (const) returned null pointer");
|
||||||
|
}
|
||||||
|
inline void pop_back() override
|
||||||
|
{
|
||||||
|
if(!len) return;
|
||||||
|
|
||||||
|
if(!inserter.pop_n(sizeof(T))) panic("pop_back(): 0 elements");
|
||||||
|
len-=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const std::size_t size() const override { return len; }
|
||||||
|
private:
|
||||||
|
file_back_buffer inserter;
|
||||||
|
std::size_t len=0;
|
||||||
|
mutable std::vector<unsigned char> current_back; // what an awful hack...
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, std::size_t Spill = FSV_DEFAULT_SPILL_AT >
|
||||||
|
requires (Spill > 0)
|
||||||
|
struct fixed_spill_vector : public i_back_inserter<T>
|
||||||
|
{
|
||||||
|
constexpr const static std::size_t SPILL_AT = Spill;
|
||||||
|
|
||||||
|
inline fixed_spill_vector() : mem(std::make_unique<std::array<T, Spill> >()){
|
||||||
|
D_dprintf("alloc cap (static): %lu", Spill);
|
||||||
|
}
|
||||||
|
inline fixed_spill_vector(const fixed_spill_vector<T>& c) = delete;
|
||||||
|
inline fixed_spill_vector(fixed_spill_vector<T>&& m)
|
||||||
|
: mem(std::move(m.mem)),
|
||||||
|
mem_fill_ptr(m.mem_fill_ptr),
|
||||||
|
fil(std::move(m.fil))
|
||||||
|
{}
|
||||||
|
inline ~fixed_spill_vector() = default;
|
||||||
|
|
||||||
|
inline void push_back(T&& value) override
|
||||||
|
{
|
||||||
|
if(mem_is_full()) {
|
||||||
|
//D_dprintf("Inserting value into fs");
|
||||||
|
fil.push_back(std::move(value));
|
||||||
|
} else {
|
||||||
|
//D_dprintf("Inserting value into memory");
|
||||||
|
(*mem)[++mem_fill_ptr] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline void pop_back() override
|
||||||
|
{
|
||||||
|
if(!size()) return;
|
||||||
|
|
||||||
|
if(fil.size()) {
|
||||||
|
//D_dprintf("Popping from fs");
|
||||||
|
fil.pop_back();
|
||||||
|
} else {
|
||||||
|
//D_dprintf("Popping from memory %ld", mem_fill_ptr);
|
||||||
|
mem_fill_ptr -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline const T& back() const override
|
||||||
|
{
|
||||||
|
if (!size()) panic("back() (const) called on no elements");
|
||||||
|
if(fil.size()) return fil.back();
|
||||||
|
else return (*mem)[mem_fill_ptr];
|
||||||
|
}
|
||||||
|
inline T& back() override
|
||||||
|
{
|
||||||
|
if (!size()) panic("back() called on no elements");
|
||||||
|
if(fil.size()) return fil.back();
|
||||||
|
else return (*mem)[mem_fill_ptr];
|
||||||
|
}
|
||||||
|
inline const std::size_t size() const override
|
||||||
|
{
|
||||||
|
return fil.size() + (std::size_t)(mem_fill_ptr+1);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
inline bool mem_is_full() const { return mem_fill_ptr >= (ssize_t)(Spill-1); }
|
||||||
|
ssize_t mem_fill_ptr=-1;
|
||||||
|
|
||||||
|
std::unique_ptr<std::array<T, Spill>> mem;
|
||||||
|
file_vector<T> fil;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct mapped_vector : public i_back_inserter<T>, public i_shunt
|
||||||
|
{
|
||||||
|
inline static mapped_vector<T> from_temp(std::size_t sz)
|
||||||
|
{
|
||||||
|
D_dprintf("generating with %lu size", sz);
|
||||||
|
temp_file file;
|
||||||
|
mapped_vector<T> mvec(file.full_path().c_str(), sz);
|
||||||
|
D_dprintf("generated?");
|
||||||
|
mvec.temp = std::make_unique<temp_file>(std::move(file));
|
||||||
|
return mvec;
|
||||||
|
}
|
||||||
|
inline mapped_vector(const char* file, std::size_t sz)
|
||||||
|
: sz(sz),
|
||||||
|
temp(nullptr),
|
||||||
|
map(mm::mmap::allocate(file, sz * sizeof(T))){}
|
||||||
|
inline mapped_vector(const mapped_vector<T>& c) = delete;
|
||||||
|
inline mapped_vector(mapped_vector<T>&& m)
|
||||||
|
: sz(m.sz),
|
||||||
|
fill_ptr(m.fill_ptr),
|
||||||
|
temp(std::move(m.temp)),
|
||||||
|
map(std::move(m.map)){}
|
||||||
|
inline mapped_vector() : mapped_vector(nullptr, 0)
|
||||||
|
{
|
||||||
|
panic("unsupported");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void push_back(T&& value) override
|
||||||
|
{
|
||||||
|
if(is_full()) panic("Tried to push past end of map");
|
||||||
|
else memory()[++fill_ptr] = value;
|
||||||
|
}
|
||||||
|
inline void pop_back() override
|
||||||
|
{
|
||||||
|
if(fill_ptr>=0) fill_ptr-=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T& back() override
|
||||||
|
{
|
||||||
|
if(fill_ptr>=0)
|
||||||
|
{
|
||||||
|
return memory()[fill_ptr];
|
||||||
|
} else panic("back() called with no elements");
|
||||||
|
}
|
||||||
|
inline const T& back() const override
|
||||||
|
{
|
||||||
|
if(fill_ptr>=0)
|
||||||
|
{
|
||||||
|
return memory()[fill_ptr];
|
||||||
|
} else panic("back() const called with no elements");
|
||||||
|
}
|
||||||
|
inline const std::size_t size() const override { return ((std::size_t)fill_ptr)+1; }
|
||||||
|
inline std::size_t cap() const { return sz; }
|
||||||
|
|
||||||
|
inline bool is_full() const { return fill_ptr >= (ssize_t)(sz-1); }
|
||||||
|
protected:
|
||||||
|
inline const span<T> memory() const { return map.as_span().reinterpret<T>(); }
|
||||||
|
inline span<T> memory() { return map.as_span().reinterpret<T>(); }
|
||||||
|
private:
|
||||||
|
std::size_t sz;
|
||||||
|
ssize_t fill_ptr=-1;
|
||||||
|
|
||||||
|
std::unique_ptr<temp_file> temp;
|
||||||
|
mm::mmap map;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, typename Shunt>
|
||||||
|
requires(std::is_base_of<i_back_inserter<T>, Shunt >::value)
|
||||||
|
struct shunt : public i_back_inserter<T>, protected i_shunt
|
||||||
|
{
|
||||||
|
typedef Shunt spill_type;
|
||||||
|
|
||||||
|
inline shunt() : shunt(FSV_DEFAULT_SPILL_AT){}
|
||||||
|
inline shunt(spill_type&& into) : shunt(FSV_DEFAULT_SPILL_AT, std::move(into)){}
|
||||||
|
inline shunt(std::size_t cap) : shunt(cap, cap){}
|
||||||
|
inline shunt(std::size_t cap, spill_type&& into) : shunt(cap, cap, std::move(into)){}
|
||||||
|
inline shunt(std::size_t cap, std::size_t spill, spill_type&& into)
|
||||||
|
: _spill_at(spill), mem(std::vector<T>()), fil(std::make_unique<spill_type>(std::move(into))) {
|
||||||
|
mem.reserve(cap);
|
||||||
|
|
||||||
|
D_dprintf("alloc (explicit) cap %lu (sz %lu == 0?), spill %lu", cap, mem.size(), spill_at());
|
||||||
|
}
|
||||||
|
inline shunt(std::size_t cap, std::size_t spill) : _spill_at(spill), mem(std::vector<T>()), fil(nullptr) {
|
||||||
|
mem.reserve(cap);
|
||||||
|
D_dprintf("alloc cap %lu (sz %lu == 0?), spill %lu", cap, mem.size(), spill_at());
|
||||||
|
}
|
||||||
|
inline shunt(const shunt<T, Shunt>& c) = delete;
|
||||||
|
inline shunt(shunt<T, Shunt>&& m) :
|
||||||
|
_spill_at(m._spill_at),
|
||||||
|
mem(std::move(m.mem)),
|
||||||
|
fil(std::move(m.fil)){}
|
||||||
|
|
||||||
|
inline void push_back(T&& value) override
|
||||||
|
{
|
||||||
|
if(is_full()) {
|
||||||
|
spl()->push_back(std::move(value));
|
||||||
|
}
|
||||||
|
else mem.push_back(std::move(value));
|
||||||
|
}
|
||||||
|
inline void pop_back() override
|
||||||
|
{
|
||||||
|
if(is_full() && spl()->size()) spl()->pop_back();
|
||||||
|
else mem.pop_back();
|
||||||
|
}
|
||||||
|
inline const T& back() const override
|
||||||
|
{
|
||||||
|
if(is_full() && spl()->size()) return spl()->back();
|
||||||
|
else return mem.back();
|
||||||
|
}
|
||||||
|
inline T& back() override
|
||||||
|
{
|
||||||
|
if(is_full() && spl()->size()) return spl()->back();
|
||||||
|
else return mem.back();
|
||||||
|
}
|
||||||
|
inline const std::size_t size() const override { return mem.size() + (fil ? fil->size() : 0); }
|
||||||
|
|
||||||
|
inline const std::size_t spill_at() const { return _spill_at; }
|
||||||
|
inline bool is_spilling() const { return is_full(); }
|
||||||
|
protected:
|
||||||
|
inline bool is_full() const override { return size()>=spill_at(); }
|
||||||
|
private:
|
||||||
|
inline const spill_type* spl() const
|
||||||
|
{
|
||||||
|
if(is_full()) {
|
||||||
|
if(!fil) fil = std::make_unique<spill_type>();
|
||||||
|
return fil.get();
|
||||||
|
} else {
|
||||||
|
return fil.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline spill_type* spl()
|
||||||
|
{
|
||||||
|
if(is_full()) {
|
||||||
|
if(!fil) fil = std::make_unique<spill_type>();
|
||||||
|
return fil.get();
|
||||||
|
} else {
|
||||||
|
return fil.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::size_t _spill_at;
|
||||||
|
std::vector<T> mem;
|
||||||
|
mutable std::unique_ptr<spill_type> fil;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using dynamic_spill_vector = shunt<T, file_vector<T> >;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using mapped_spill_vector = shunt<T, mapped_vector<T> >;
|
@ -0,0 +1,406 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
#include <array>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#error "C++ header only"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace pr {
|
||||||
|
|
||||||
|
namespace details [[gnu::visibility("internal")]] {
|
||||||
|
/*
|
||||||
|
template<template<typename...> typename P>
|
||||||
|
struct generic_valid { template<typename... Args> constexpr static inline bool value = requires{ typename P<Args...>; }; };
|
||||||
|
template<template<typename...> class P>
|
||||||
|
struct generic : std::conditional_t<generic_valid<P>::value,
|
||||||
|
std::true_type,
|
||||||
|
std::false_type>
|
||||||
|
{ template<typename... Args> using type = P<Args...>; };
|
||||||
|
|
||||||
|
template<template<typename> typename T, typename... Args>
|
||||||
|
concept Generic = generic_valid<T>::template value<Args...>;
|
||||||
|
|
||||||
|
template<Generic T, typename... Args>
|
||||||
|
using generic_t = generic<T>::template type<Args...>;
|
||||||
|
|
||||||
|
template<template<typename> template T>
|
||||||
|
concept AnyGeneric = requires{ typename generic_valid<T>; };
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
T* take(T*&& ptr) noexcept { return std::exchange(ptr, nullptr); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
template<template<typename U> Inst, typename T>
|
||||||
|
struct is_inst_of { constexpr static inline bool value = std::is_same_v<T, Inst<U>>; };
|
||||||
|
|
||||||
|
template<typename T, typename I>
|
||||||
|
constexpr inline bool is_inst_of_v = is_inst_of<I, T>::value;
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename U, typename T>
|
||||||
|
constexpr std::unique_ptr<U> static_ucast(std::unique_ptr<T>&& from) noexcept
|
||||||
|
{ return std::unique_ptr<U>{static_cast<U*>(std::move(from).release())}; }
|
||||||
|
|
||||||
|
template<typename U, typename T>
|
||||||
|
constexpr std::shared_ptr<U> static_ucast(std::shared_ptr<T>&& from) noexcept
|
||||||
|
{ return std::static_pointer_cast<U>(std::move(from)); }
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Ptr, typename From> requires(requires(From&& p) {
|
||||||
|
{ p.release() };
|
||||||
|
requires(std::is_constructible_v<Ptr, decltype(p.release())>);
|
||||||
|
})
|
||||||
|
constexpr Ptr static_pcast(From&& p) noexcept { return Ptr{p.release()}; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
using increment_t = long double;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
concept Bar = requires(std::remove_const_t<std::remove_reference_t<T>>& v) {
|
||||||
|
{ v.spin(increment_t(0)) };
|
||||||
|
{ std::as_const(v).aux() } -> std::convertible_to<std::string_view>;
|
||||||
|
//{ v.aux() } -> std::assignable_from<std::string_view>;
|
||||||
|
{ (v.aux() = std::string{}) } -> std::same_as<std::add_lvalue_reference_t<decltype(v.aux())>>;
|
||||||
|
//requires(std::assignable_from<std::add_lvalue_reference_t<decltype(v.aux())>, std::string_view>);
|
||||||
|
{ v.aux() += std::string_view{} } -> std::convertible_to<decltype(v.aux())>;
|
||||||
|
{ v.aux(std::declval<std::string&&>()) } -> std::convertible_to<std::string_view>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<Bar>
|
||||||
|
struct Carrier;
|
||||||
|
|
||||||
|
struct Dynamic {
|
||||||
|
template<Bar> friend class Carrier;
|
||||||
|
|
||||||
|
constexpr auto make(Bar auto&& bar) noexcept(std::is_nothrow_move_constructible_v<std::remove_reference_t<decltype(bar)>>);
|
||||||
|
|
||||||
|
constexpr virtual void spin(increment_t) =0;
|
||||||
|
constexpr virtual std::string& aux() =0;
|
||||||
|
constexpr virtual std::string const& aux() const noexcept =0;
|
||||||
|
constexpr virtual std::string aux(std::string&& s) { return std::exchange(aux(), std::move(s)); }
|
||||||
|
|
||||||
|
constexpr virtual ~Dynamic() {}
|
||||||
|
private:
|
||||||
|
constexpr Dynamic() noexcept {}
|
||||||
|
};
|
||||||
|
template<Bar B>
|
||||||
|
struct Carrier : public virtual Dynamic {
|
||||||
|
using held_type = B;
|
||||||
|
|
||||||
|
template<typename... Args> requires(std::constructible_from<B, Args...>)
|
||||||
|
constexpr Carrier(Args&&... args) noexcept(std::is_nothrow_constructible_v<B, Args...>)
|
||||||
|
: Dynamic(), member_(std::forward<decltype(args)>(args)...) {}
|
||||||
|
constexpr Carrier(Carrier&& m) noexcept(std::is_nothrow_move_constructible_v<B>)
|
||||||
|
requires(std::is_move_constructible_v<B>)
|
||||||
|
: Dynamic(), member_(std::move(m.member_)) {}
|
||||||
|
constexpr Carrier(Carrier const& c) noexcept(std::is_nothrow_copy_constructible_v<B>)
|
||||||
|
requires(std::is_copy_constructible_v<B>)
|
||||||
|
: Dynamic(), member_(c.member_) {}
|
||||||
|
|
||||||
|
constexpr Carrier& operator=(Carrier&& m) noexcept(std::is_nothrow_move_assignable_v<B>) requires(std::is_move_assignable_v<B>)
|
||||||
|
{ if(this != &m) member_ = std::move(m.member_); return *this; }
|
||||||
|
|
||||||
|
constexpr Carrier& operator=(Carrier const& c) noexcept(std::is_nothrow_copy_assignable_v<B>) requires(std::is_copy_assignable_v<B>)
|
||||||
|
{ if(this != &c) member_ = c.member_; return *this; }
|
||||||
|
|
||||||
|
constexpr void spin(increment_t a) override { member_.spin(a); }
|
||||||
|
|
||||||
|
constexpr std::string& aux() override { return member_.aux(); }
|
||||||
|
constexpr std::string const& aux() const noexcept override { return member_.aux(); }
|
||||||
|
constexpr std::string aux(std::string&& s) override { return member_.aux(std::move(s)); }
|
||||||
|
|
||||||
|
template<typename... Args> requires(std::is_invocable_v<B::spin, B&, increment_t, Args...>)
|
||||||
|
constexpr void spin(increment_t a, Args&&... args) noexcept(std::is_nothrow_invocable_v<B::spin, B&, increment_t, decltype(args)...>)
|
||||||
|
{ return member_.spin(a, std::forward<decltype(args)>(args)...); }
|
||||||
|
|
||||||
|
constexpr virtual ~Carrier() {}
|
||||||
|
private:
|
||||||
|
B member_;
|
||||||
|
};
|
||||||
|
template<Bar T>
|
||||||
|
Carrier(T) -> Carrier<T>;
|
||||||
|
template<Bar T>
|
||||||
|
Carrier(T const&) -> Carrier<T>;
|
||||||
|
template<Bar T>
|
||||||
|
Carrier(T&&) -> Carrier<T>;
|
||||||
|
|
||||||
|
constexpr auto Dynamic::make(Bar auto&& bar) noexcept(std::is_nothrow_move_constructible_v<std::remove_reference_t<decltype(bar)>>) { return Carrier(std::move(bar)); }
|
||||||
|
|
||||||
|
template<Bar T, typename Ptr = std::unique_ptr<Dynamic>>
|
||||||
|
constexpr Ptr make_dyn(T&& bar) noexcept(std::is_nothrow_move_constructible_v<T>)
|
||||||
|
{
|
||||||
|
using namespace details;
|
||||||
|
if constexpr(requires{
|
||||||
|
typename T::held_type;
|
||||||
|
requires(std::is_same_v<Carrier<typename T::held_type>, T>);
|
||||||
|
}) return static_pcast<Ptr>(static_ucast<Dynamic>(std::make_unique<T>(std::move(bar))));
|
||||||
|
else return static_pcast<Ptr>(static_ucast<Dynamic>(std::make_unique<Carrier<T>>(std::move(bar))));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Bar T, typename Ptr = std::unique_ptr<Dynamic>>
|
||||||
|
constexpr Ptr make_dyn(T const& bar) noexcept(std::is_nothrow_move_constructible_v<T>)
|
||||||
|
{
|
||||||
|
if constexpr(std::is_copy_constructible_v<T>) {
|
||||||
|
T nbar{bar};
|
||||||
|
return make_dyn<T, Ptr>(std::move(nbar));
|
||||||
|
} else {
|
||||||
|
struct unsafe_ref {
|
||||||
|
constexpr unsafe_ref(const T& ba) noexcept : b(std::addressof(ba)) {}
|
||||||
|
constexpr unsafe_ref(const unsafe_ref&) noexcept = default;
|
||||||
|
constexpr ~unsafe_ref() noexcept = default;
|
||||||
|
constexpr unsafe_ref(unsafe_ref&& b) noexcept : b(std::exchange(b.b, nullptr)) {}
|
||||||
|
|
||||||
|
constexpr unsafe_ref& operator=(unsafe_ref const&) noexcept = default;
|
||||||
|
constexpr unsafe_ref& operator=(unsafe_ref&& m) noexcept {
|
||||||
|
if(this != &m)
|
||||||
|
b = std::exchange(m.b, nullptr);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* b;
|
||||||
|
|
||||||
|
constexpr operator T const&() const noexcept { return *b; }
|
||||||
|
};
|
||||||
|
unsafe_ref re{bar};
|
||||||
|
return make_dyn<unsafe_ref, Ptr>(std::move(re));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ptr> requires(requires(std::unique_ptr<Dynamic>&& p) { details::static_pcast<Ptr>(std::move(p)); })
|
||||||
|
constexpr Ptr make_dyn_for(Bar auto&& bar) noexcept(std::is_nothrow_move_constructible_v<std::remove_reference_t<decltype(bar)>>)
|
||||||
|
{ return make_dyn<decltype(bar), Ptr>(std::move(bar)); }
|
||||||
|
|
||||||
|
constexpr void spin(Bar auto& bar, std::convertible_to<increment_t> auto&& a) { return bar.spin(increment_t(a)); }
|
||||||
|
|
||||||
|
struct None {
|
||||||
|
constexpr None() noexcept = default;
|
||||||
|
constexpr ~None() noexcept = default;
|
||||||
|
|
||||||
|
constexpr void spin(increment_t) const noexcept {}
|
||||||
|
constexpr auto aux() noexcept { return not_string(); }
|
||||||
|
inline std::string const& aux() const noexcept { return none_; }
|
||||||
|
constexpr std::string aux(std::convertible_to<std::string> auto&& s) const noexcept { return {}; } //{ return std::exchange(none_, std::string(std::move(s))); }
|
||||||
|
private:
|
||||||
|
struct not_string {
|
||||||
|
constexpr not_string() noexcept= default;
|
||||||
|
constexpr ~not_string() noexcept= default;
|
||||||
|
|
||||||
|
[[gnu::const]]
|
||||||
|
constexpr not_string& operator+=(std::convertible_to<std::string_view> auto&&) { return *this; }
|
||||||
|
[[gnu::const]]
|
||||||
|
constexpr not_string& operator=(std::convertible_to<std::string> auto&&) { return *this; }
|
||||||
|
|
||||||
|
inline operator std::string&() noexcept { return none_; }
|
||||||
|
inline operator std::string const&() const noexcept { return none_; }
|
||||||
|
|
||||||
|
};
|
||||||
|
/*constinit*/ thread_local static inline std::string none_;
|
||||||
|
};
|
||||||
|
constexpr inline None disable{};
|
||||||
|
|
||||||
|
// A bounded progress-bar
|
||||||
|
struct Progress {
|
||||||
|
using fract_t = increment_t;
|
||||||
|
constexpr static inline bool DEFAULT_WIDTH = 50;
|
||||||
|
constexpr static inline fract_t DEFAULT_TERM_FRACT=1.0l/3.0l;
|
||||||
|
|
||||||
|
[[gnu::nonnull(1)]]
|
||||||
|
Progress(FILE* p = stdout) noexcept;
|
||||||
|
|
||||||
|
Progress(const Progress& p) noexcept;
|
||||||
|
Progress(Progress&& p) noexcept;
|
||||||
|
|
||||||
|
Progress& operator=(Progress const& c) noexcept;
|
||||||
|
Progress& operator=(Progress&& m) noexcept;
|
||||||
|
|
||||||
|
virtual ~Progress();
|
||||||
|
|
||||||
|
inline std::string& aux() noexcept { return tag(); }
|
||||||
|
inline std::string const& aux() const noexcept { return tag(); }
|
||||||
|
inline std::string aux(std::convertible_to<std::string> auto&& s)
|
||||||
|
{ return std::exchange(tag(), std::string(std::move(s))); }
|
||||||
|
protected:
|
||||||
|
std::string& tag() noexcept;
|
||||||
|
const std::string& tag() const noexcept;
|
||||||
|
public:
|
||||||
|
FILE* output() const noexcept;
|
||||||
|
FILE*& output() noexcept;
|
||||||
|
|
||||||
|
size_t& width() noexcept;
|
||||||
|
size_t width() const noexcept;
|
||||||
|
|
||||||
|
fract_t& fraction() noexcept;
|
||||||
|
fract_t fraction() const noexcept;
|
||||||
|
|
||||||
|
fract_t percentage() const noexcept;
|
||||||
|
inline auto percentage() noexcept {
|
||||||
|
struct v final {
|
||||||
|
Progress* p_;
|
||||||
|
v(Progress* p) noexcept : p_(p) {}
|
||||||
|
|
||||||
|
v(v&&) noexcept = default;
|
||||||
|
v(v const&) noexcept = default;
|
||||||
|
v& operator=(v const&) noexcept = default;
|
||||||
|
v& operator=(v&&) noexcept = default;
|
||||||
|
~v() noexcept = default;
|
||||||
|
|
||||||
|
const v& operator=(fract_t f) const noexcept { p_->percentage(f); return *this; }
|
||||||
|
operator fract_t() const noexcept { return static_cast<const Progress*>(p_)->percentage(); }
|
||||||
|
};
|
||||||
|
return v(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spin(increment_t by, bool render=true, bool flush=true) noexcept;
|
||||||
|
void render(bool flush = true) const noexcept;
|
||||||
|
private:
|
||||||
|
void percentage(fract_t fract) noexcept;
|
||||||
|
|
||||||
|
struct _impl;
|
||||||
|
std::shared_ptr<_impl> inner_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SPINNER
|
||||||
|
class Spinner {
|
||||||
|
consteval static auto _GENERATE_MAP(auto const& map, size_t size) noexcept
|
||||||
|
-> std::array<size_t, 256>
|
||||||
|
{
|
||||||
|
static_assert(sizeof(map) == size, "Bad map size");
|
||||||
|
std::array<size_t, 256> out{};
|
||||||
|
while( size --> 0 ) out[int(map[size])] = size;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
constexpr static increment_t range(increment_t by)
|
||||||
|
{
|
||||||
|
if(by < -1.0l) return -1.0l;
|
||||||
|
else if(by > 1.0l) return 1.0l;
|
||||||
|
return by;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
constexpr static inline auto ROUTINE = "|/-\\|/-\\|";
|
||||||
|
constexpr static inline auto ROUTINE_SIZE = sizeof(ROUTINE);
|
||||||
|
constexpr static inline auto REVERSE_MAP = _GENERATE_MAP(ROUTINE, ROUTINE_SIZE);
|
||||||
|
static_assert(ROUTINE_SIZE != sizeof(char*), "Invalid routine size");
|
||||||
|
|
||||||
|
constexpr ssize_t range(int sz) noexcept
|
||||||
|
{
|
||||||
|
/*if(__builtin_expect(sz < 0, false)) {
|
||||||
|
|
||||||
|
std::terminate(); // TODO: How to handle wrapping negatives?? Ugh.
|
||||||
|
}*/
|
||||||
|
return ssize_t(sz) % ssize_t(ROUTINE_SIZE);
|
||||||
|
}
|
||||||
|
constexpr Spinner(size_t n) noexcept
|
||||||
|
: cur_(ROUTINE[range(n)]) {}
|
||||||
|
constexpr Spinner(char c = ROUTINE[0]) noexcept
|
||||||
|
: cur_(range(REVERSE_MAP[int(c)])) {}
|
||||||
|
|
||||||
|
constexpr Spinner(Spinner const&) noexcept = default;
|
||||||
|
constexpr Spinner(Spinner &&) noexcept = default;
|
||||||
|
~Spinner();
|
||||||
|
|
||||||
|
inline void spin(int by) noexcept
|
||||||
|
{
|
||||||
|
operator+=(by);
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
inline void spin(increment_by by) noexcept
|
||||||
|
{
|
||||||
|
spin(int(range(by) * increment_t(ROUTINE_SIZE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Spinner& operator+=(int by) noexcept
|
||||||
|
{
|
||||||
|
cur_ = ROUTINE[size_t(ssize_t(REVERSE_MAP[int(cur_)]) + range(by))];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Spinner& operator++() noexcept { spin(1); return *this; }
|
||||||
|
inline Spinner operator++(int) noexcept { Spinner s = *this; ++s; return *this; }
|
||||||
|
constexpr Spinner& operator=(Spinner&&) noexcept = default;
|
||||||
|
constexpr Spinner& operator=(Spinner const&) noexcept = default;
|
||||||
|
|
||||||
|
constexpr char& character() noexcept { return cur_; }
|
||||||
|
constexpr char character() const noexcept { return cur_; }
|
||||||
|
|
||||||
|
void render(bool flush=true);
|
||||||
|
private:
|
||||||
|
char cur_ = '|';
|
||||||
|
};
|
||||||
|
//TODO: Spinny bar thing (unbounded)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct Bar {
|
||||||
|
Bar() noexcept = default;
|
||||||
|
Bar(const Bar&) noexcept = default;
|
||||||
|
Bar(Bar&&) noexcept = default;
|
||||||
|
Bar& operator=(const Bar&) noexcept = default;
|
||||||
|
Bar& operator=(Bar&&) noexcept = default;
|
||||||
|
virtual ~Bar() = default;
|
||||||
|
|
||||||
|
virtual void spin(int) =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum bar_kind {
|
||||||
|
BRK_UNTRACKED,
|
||||||
|
BRK_TRACKED,
|
||||||
|
};
|
||||||
|
|
||||||
|
template<bar_kind = BRK_UNTRACKED>
|
||||||
|
struct progress;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct progress<BRK_UNTRACKED>
|
||||||
|
: public virtual Bar {
|
||||||
|
|
||||||
|
progress(FILE* to);
|
||||||
|
progress(progress const&);
|
||||||
|
inline progress(progress&& mv) noexcept
|
||||||
|
: Bar()
|
||||||
|
, _perc(mv._perc)
|
||||||
|
, _output(details::take(mv._output)) {}
|
||||||
|
|
||||||
|
virtual ~progress();
|
||||||
|
|
||||||
|
void spin(int) override;
|
||||||
|
|
||||||
|
//TODO: this
|
||||||
|
protected:
|
||||||
|
union {
|
||||||
|
double _perc;
|
||||||
|
size_t _num; // not used here
|
||||||
|
};
|
||||||
|
FILE* _output;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class progress<BRK_TRACKED>
|
||||||
|
: public progress<BRK_UNTRACKED> {
|
||||||
|
using base_t = progress<BRK_UNTRACKED>;
|
||||||
|
public:
|
||||||
|
inline progress(FILE* to, size_t max) : base_t(to), _num(0), _max(max) {}
|
||||||
|
progress(const progress&) = default;
|
||||||
|
progress(progress&& m) : base_t(std::move(m)), _num(std::exchange(m._num, 0)), _max(m._max) {}
|
||||||
|
|
||||||
|
void spin(int) override;
|
||||||
|
//TODO: this
|
||||||
|
|
||||||
|
virtual ~progress() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using base_t::_output;
|
||||||
|
private:
|
||||||
|
using base_t::_num;
|
||||||
|
size_t _max;
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
#pragma once
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include "uuid.hpp"
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
using std::size_t;
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
/// A temporary file name
|
||||||
|
struct temp_file
|
||||||
|
{
|
||||||
|
inline temp_file(const temp_file& c) = delete;
|
||||||
|
|
||||||
|
inline temp_file(temp_file&& m) : name(std::move(m.name)), _full_path(std::move(m._full_path)) {}
|
||||||
|
inline temp_file() : name(uuid::generate().to_string()+"-s3"){}
|
||||||
|
inline temp_file(const char* name) : name(name) {}
|
||||||
|
inline temp_file(std::string&& name) : name(name) {}
|
||||||
|
|
||||||
|
inline ~temp_file()
|
||||||
|
{
|
||||||
|
if(name.empty() && _full_path.empty()) return;
|
||||||
|
|
||||||
|
D_dprintf("~tempfile(): %s", _full_path.c_str());
|
||||||
|
|
||||||
|
if(!_full_path.empty() && fs::exists(_full_path) ) {
|
||||||
|
D_dprintf("tfile removing: %s", _full_path.c_str());
|
||||||
|
fs::remove(_full_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const fs::path& full_path() const
|
||||||
|
{
|
||||||
|
if(_full_path.empty()) {
|
||||||
|
_full_path = fs::absolute( fs::temp_directory_path() / name );
|
||||||
|
D_dprintf("tfile path: %s", _full_path.c_str());
|
||||||
|
}
|
||||||
|
return _full_path;
|
||||||
|
}
|
||||||
|
inline const std::string& base_name() const { return name; }
|
||||||
|
|
||||||
|
inline const fs::path* operator->() const { return &full_path(); }
|
||||||
|
private:
|
||||||
|
std::string name;
|
||||||
|
mutable fs::path _full_path;
|
||||||
|
};
|
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <random>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct uuid //not to spec but idc
|
||||||
|
{
|
||||||
|
const static constexpr int SIZE=16;
|
||||||
|
inline static uuid generate()
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
static thread_local random_device dev;
|
||||||
|
static thread_local mt19937 rng(dev());
|
||||||
|
uniform_int_distribution<int> dist(0, 15);
|
||||||
|
constexpr const char hex[] = "0123456789abcdef";
|
||||||
|
uuid id;
|
||||||
|
for(int i=0;i<SIZE;i++) id.str[i] = hex[dist(rng)];
|
||||||
|
id.str[SIZE] =0;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
inline operator const char*() const { return &str[0]; }
|
||||||
|
inline operator const std::array<char, SIZE+1>&() const { return str; }
|
||||||
|
|
||||||
|
inline std::string to_string() const
|
||||||
|
{
|
||||||
|
return std::string(&str[0]);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
inline uuid(){}
|
||||||
|
std::array<char, SIZE+1> str;
|
||||||
|
};
|
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 51 KiB |
@ -0,0 +1,567 @@
|
|||||||
|
desc: (none)
|
||||||
|
cmd: ./shuffle3-release small-u
|
||||||
|
time_unit: i
|
||||||
|
#-----------
|
||||||
|
snapshot=0
|
||||||
|
#-----------
|
||||||
|
time=0
|
||||||
|
mem_heap_B=0
|
||||||
|
mem_heap_extra_B=0
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=1
|
||||||
|
#-----------
|
||||||
|
time=4048133
|
||||||
|
mem_heap_B=32816
|
||||||
|
mem_heap_extra_B=8
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=2
|
||||||
|
#-----------
|
||||||
|
time=4050820
|
||||||
|
mem_heap_B=8
|
||||||
|
mem_heap_extra_B=16
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=3
|
||||||
|
#-----------
|
||||||
|
time=4057134
|
||||||
|
mem_heap_B=72712
|
||||||
|
mem_heap_extra_B=24
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=4
|
||||||
|
#-----------
|
||||||
|
time=4282565
|
||||||
|
mem_heap_B=73736
|
||||||
|
mem_heap_extra_B=32
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=5
|
||||||
|
#-----------
|
||||||
|
time=4289663
|
||||||
|
mem_heap_B=74248
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=6
|
||||||
|
#-----------
|
||||||
|
time=4295729
|
||||||
|
mem_heap_B=75784
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=7
|
||||||
|
#-----------
|
||||||
|
time=4303612
|
||||||
|
mem_heap_B=77832
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=8
|
||||||
|
#-----------
|
||||||
|
time=4318766
|
||||||
|
mem_heap_B=86024
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=9
|
||||||
|
#-----------
|
||||||
|
time=4322930
|
||||||
|
mem_heap_B=81928
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=10
|
||||||
|
#-----------
|
||||||
|
time=4353188
|
||||||
|
mem_heap_B=98312
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=11
|
||||||
|
#-----------
|
||||||
|
time=4361448
|
||||||
|
mem_heap_B=90120
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=12
|
||||||
|
#-----------
|
||||||
|
time=4421914
|
||||||
|
mem_heap_B=122888
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=13
|
||||||
|
#-----------
|
||||||
|
time=4438366
|
||||||
|
mem_heap_B=122888
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=detailed
|
||||||
|
n3: 122888 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
|
||||||
|
n1: 72704 0x493F45A: pool (eh_alloc.cc:123)
|
||||||
|
n1: 72704 0x493F45A: __static_initialization_and_destruction_0 (eh_alloc.cc:262)
|
||||||
|
n1: 72704 0x493F45A: _GLOBAL__sub_I_eh_alloc.cc (eh_alloc.cc:338)
|
||||||
|
n1: 72704 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x1: ???
|
||||||
|
n1: 72704 0x1FFF000AC6: ???
|
||||||
|
n0: 72704 0x1FFF000AD9: ???
|
||||||
|
n1: 49152 0x10A384: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n1: 49152 0x109385: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n0: 49152 0x4C6A151: (below main) (in /usr/lib/libc-2.32.so)
|
||||||
|
n0: 1032 in 3 places, all below massif's threshold (1.00%)
|
||||||
|
#-----------
|
||||||
|
snapshot=14
|
||||||
|
#-----------
|
||||||
|
time=4438366
|
||||||
|
mem_heap_B=106504
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=15
|
||||||
|
#-----------
|
||||||
|
time=4559248
|
||||||
|
mem_heap_B=172040
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=16
|
||||||
|
#-----------
|
||||||
|
time=4592084
|
||||||
|
mem_heap_B=172040
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=detailed
|
||||||
|
n3: 172040 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
|
||||||
|
n1: 98304 0x10A384: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n1: 98304 0x109385: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n0: 98304 0x4C6A151: (below main) (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 72704 0x493F45A: pool (eh_alloc.cc:123)
|
||||||
|
n1: 72704 0x493F45A: __static_initialization_and_destruction_0 (eh_alloc.cc:262)
|
||||||
|
n1: 72704 0x493F45A: _GLOBAL__sub_I_eh_alloc.cc (eh_alloc.cc:338)
|
||||||
|
n1: 72704 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x1: ???
|
||||||
|
n1: 72704 0x1FFF000AC6: ???
|
||||||
|
n0: 72704 0x1FFF000AD9: ???
|
||||||
|
n0: 1032 in 3 places, all below massif's threshold (1.00%)
|
||||||
|
#-----------
|
||||||
|
snapshot=17
|
||||||
|
#-----------
|
||||||
|
time=4592084
|
||||||
|
mem_heap_B=139272
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=18
|
||||||
|
#-----------
|
||||||
|
time=4833798
|
||||||
|
mem_heap_B=270344
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=19
|
||||||
|
#-----------
|
||||||
|
time=4899402
|
||||||
|
mem_heap_B=270344
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=detailed
|
||||||
|
n3: 270344 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
|
||||||
|
n1: 196608 0x10A384: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n1: 196608 0x109385: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n0: 196608 0x4C6A151: (below main) (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 72704 0x493F45A: pool (eh_alloc.cc:123)
|
||||||
|
n1: 72704 0x493F45A: __static_initialization_and_destruction_0 (eh_alloc.cc:262)
|
||||||
|
n1: 72704 0x493F45A: _GLOBAL__sub_I_eh_alloc.cc (eh_alloc.cc:338)
|
||||||
|
n1: 72704 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x1: ???
|
||||||
|
n1: 72704 0x1FFF000AC6: ???
|
||||||
|
n0: 72704 0x1FFF000AD9: ???
|
||||||
|
n0: 1032 in 3 places, all below massif's threshold (1.00%)
|
||||||
|
#-----------
|
||||||
|
snapshot=20
|
||||||
|
#-----------
|
||||||
|
time=4899402
|
||||||
|
mem_heap_B=204808
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=21
|
||||||
|
#-----------
|
||||||
|
time=5382780
|
||||||
|
mem_heap_B=466952
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=22
|
||||||
|
#-----------
|
||||||
|
time=5513920
|
||||||
|
mem_heap_B=466952
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=peak
|
||||||
|
n3: 466952 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
|
||||||
|
n1: 393216 0x10A384: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n1: 393216 0x109385: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n0: 393216 0x4C6A151: (below main) (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 72704 0x493F45A: pool (eh_alloc.cc:123)
|
||||||
|
n1: 72704 0x493F45A: __static_initialization_and_destruction_0 (eh_alloc.cc:262)
|
||||||
|
n1: 72704 0x493F45A: _GLOBAL__sub_I_eh_alloc.cc (eh_alloc.cc:338)
|
||||||
|
n1: 72704 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x1: ???
|
||||||
|
n1: 72704 0x1FFF000AC6: ???
|
||||||
|
n0: 72704 0x1FFF000AD9: ???
|
||||||
|
n0: 1032 in 3 places, all below massif's threshold (1.00%)
|
||||||
|
#-----------
|
||||||
|
snapshot=23
|
||||||
|
#-----------
|
||||||
|
time=5513920
|
||||||
|
mem_heap_B=335880
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=24
|
||||||
|
#-----------
|
||||||
|
time=5892087
|
||||||
|
mem_heap_B=73736
|
||||||
|
mem_heap_extra_B=32
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=25
|
||||||
|
#-----------
|
||||||
|
time=5989421
|
||||||
|
mem_heap_B=73744
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=26
|
||||||
|
#-----------
|
||||||
|
time=5996279
|
||||||
|
mem_heap_B=73992
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=27
|
||||||
|
#-----------
|
||||||
|
time=6002698
|
||||||
|
mem_heap_B=74248
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=28
|
||||||
|
#-----------
|
||||||
|
time=6015289
|
||||||
|
mem_heap_B=75272
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=29
|
||||||
|
#-----------
|
||||||
|
time=6015414
|
||||||
|
mem_heap_B=74760
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=30
|
||||||
|
#-----------
|
||||||
|
time=6040651
|
||||||
|
mem_heap_B=76808
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=31
|
||||||
|
#-----------
|
||||||
|
time=6040828
|
||||||
|
mem_heap_B=75784
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=32
|
||||||
|
#-----------
|
||||||
|
time=6091310
|
||||||
|
mem_heap_B=79880
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=detailed
|
||||||
|
n4: 79880 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
|
||||||
|
n1: 72704 0x493F45A: pool (eh_alloc.cc:123)
|
||||||
|
n1: 72704 0x493F45A: __static_initialization_and_destruction_0 (eh_alloc.cc:262)
|
||||||
|
n1: 72704 0x493F45A: _GLOBAL__sub_I_eh_alloc.cc (eh_alloc.cc:338)
|
||||||
|
n1: 72704 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x1: ???
|
||||||
|
n1: 72704 0x1FFF000AC6: ???
|
||||||
|
n0: 72704 0x1FFF000AD9: ???
|
||||||
|
n2: 6144 0x10A384: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n1: 6144 0x1095C2: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n0: 6144 0x4C6A151: (below main) (in /usr/lib/libc-2.32.so)
|
||||||
|
n0: 0 in 1 place, below massif's threshold (1.00%)
|
||||||
|
n1: 1024 0x4CB6E03: _IO_file_doallocate (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4CC570F: _IO_doallocbuf (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4CC48A7: _IO_file_overflow@@GLIBC_2.2.5 (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4CC3955: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4CB8330: fwrite (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4877FD7: fmt::v7::vprint(_IO_FILE*, fmt::v7::basic_string_view<char>, fmt::v7::format_args) (in /usr/lib/libfmt.so.7.1.2)
|
||||||
|
n1: 1024 0x10A258: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n1: 1024 0x10933E: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n0: 1024 0x4C6A151: (below main) (in /usr/lib/libc-2.32.so)
|
||||||
|
n0: 8 in 2 places, all below massif's threshold (1.00%)
|
||||||
|
#-----------
|
||||||
|
snapshot=33
|
||||||
|
#-----------
|
||||||
|
time=6091591
|
||||||
|
mem_heap_B=77832
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=34
|
||||||
|
#-----------
|
||||||
|
time=6192490
|
||||||
|
mem_heap_B=86024
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=35
|
||||||
|
#-----------
|
||||||
|
time=6196654
|
||||||
|
mem_heap_B=81928
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=36
|
||||||
|
#-----------
|
||||||
|
time=6398233
|
||||||
|
mem_heap_B=98312
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=37
|
||||||
|
#-----------
|
||||||
|
time=6406493
|
||||||
|
mem_heap_B=90120
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=38
|
||||||
|
#-----------
|
||||||
|
time=6809904
|
||||||
|
mem_heap_B=122888
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=39
|
||||||
|
#-----------
|
||||||
|
time=6826356
|
||||||
|
mem_heap_B=106504
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=40
|
||||||
|
#-----------
|
||||||
|
time=7633039
|
||||||
|
mem_heap_B=172040
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=41
|
||||||
|
#-----------
|
||||||
|
time=7665875
|
||||||
|
mem_heap_B=139272
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=42
|
||||||
|
#-----------
|
||||||
|
time=7951930
|
||||||
|
mem_heap_B=73736
|
||||||
|
mem_heap_extra_B=32
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=detailed
|
||||||
|
n3: 73736 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
|
||||||
|
n1: 72704 0x493F45A: pool (eh_alloc.cc:123)
|
||||||
|
n1: 72704 0x493F45A: __static_initialization_and_destruction_0 (eh_alloc.cc:262)
|
||||||
|
n1: 72704 0x493F45A: _GLOBAL__sub_I_eh_alloc.cc (eh_alloc.cc:338)
|
||||||
|
n1: 72704 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x1: ???
|
||||||
|
n1: 72704 0x1FFF000AC6: ???
|
||||||
|
n0: 72704 0x1FFF000AD9: ???
|
||||||
|
n1: 1024 0x4CB6E03: _IO_file_doallocate (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4CC570F: _IO_doallocbuf (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4CC48A7: _IO_file_overflow@@GLIBC_2.2.5 (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4CC3955: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4CB8330: fwrite (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4877FD7: fmt::v7::vprint(_IO_FILE*, fmt::v7::basic_string_view<char>, fmt::v7::format_args) (in /usr/lib/libfmt.so.7.1.2)
|
||||||
|
n1: 1024 0x10A258: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n1: 1024 0x10933E: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n0: 1024 0x4C6A151: (below main) (in /usr/lib/libc-2.32.so)
|
||||||
|
n0: 8 in 3 places, all below massif's threshold (1.00%)
|
||||||
|
#-----------
|
||||||
|
snapshot=43
|
||||||
|
#-----------
|
||||||
|
time=7971885
|
||||||
|
mem_heap_B=73744
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=44
|
||||||
|
#-----------
|
||||||
|
time=7979276
|
||||||
|
mem_heap_B=75784
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=45
|
||||||
|
#-----------
|
||||||
|
time=7985879
|
||||||
|
mem_heap_B=77832
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=46
|
||||||
|
#-----------
|
||||||
|
time=7998473
|
||||||
|
mem_heap_B=86024
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=detailed
|
||||||
|
n4: 86024 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
|
||||||
|
n1: 72704 0x493F45A: pool (eh_alloc.cc:123)
|
||||||
|
n1: 72704 0x493F45A: __static_initialization_and_destruction_0 (eh_alloc.cc:262)
|
||||||
|
n1: 72704 0x493F45A: _GLOBAL__sub_I_eh_alloc.cc (eh_alloc.cc:338)
|
||||||
|
n1: 72704 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
|
||||||
|
n1: 72704 0x1: ???
|
||||||
|
n1: 72704 0x1FFF000AC6: ???
|
||||||
|
n0: 72704 0x1FFF000AD9: ???
|
||||||
|
n2: 12288 0x10A384: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n1: 12288 0x10973E: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n0: 12288 0x4C6A151: (below main) (in /usr/lib/libc-2.32.so)
|
||||||
|
n0: 0 in 2 places, all below massif's threshold (1.00%)
|
||||||
|
n1: 1024 0x4CB6E03: _IO_file_doallocate (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4CC570F: _IO_doallocbuf (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4CC48A7: _IO_file_overflow@@GLIBC_2.2.5 (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4CC3955: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4CB8330: fwrite (in /usr/lib/libc-2.32.so)
|
||||||
|
n1: 1024 0x4877FD7: fmt::v7::vprint(_IO_FILE*, fmt::v7::basic_string_view<char>, fmt::v7::format_args) (in /usr/lib/libfmt.so.7.1.2)
|
||||||
|
n1: 1024 0x10A258: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n1: 1024 0x10933E: ??? (in /home/avril/work/shuffle3/lean/shuffle3-release)
|
||||||
|
n0: 1024 0x4C6A151: (below main) (in /usr/lib/libc-2.32.so)
|
||||||
|
n0: 8 in 2 places, all below massif's threshold (1.00%)
|
||||||
|
#-----------
|
||||||
|
snapshot=47
|
||||||
|
#-----------
|
||||||
|
time=8002637
|
||||||
|
mem_heap_B=81928
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=48
|
||||||
|
#-----------
|
||||||
|
time=8027775
|
||||||
|
mem_heap_B=98312
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=49
|
||||||
|
#-----------
|
||||||
|
time=8036035
|
||||||
|
mem_heap_B=90120
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=50
|
||||||
|
#-----------
|
||||||
|
time=8086261
|
||||||
|
mem_heap_B=122888
|
||||||
|
mem_heap_extra_B=48
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=51
|
||||||
|
#-----------
|
||||||
|
time=8102713
|
||||||
|
mem_heap_B=106504
|
||||||
|
mem_heap_extra_B=40
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=52
|
||||||
|
#-----------
|
||||||
|
time=8147526
|
||||||
|
mem_heap_B=73736
|
||||||
|
mem_heap_extra_B=32
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=53
|
||||||
|
#-----------
|
||||||
|
time=8156172
|
||||||
|
mem_heap_B=1032
|
||||||
|
mem_heap_extra_B=24
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
||||||
|
#-----------
|
||||||
|
snapshot=54
|
||||||
|
#-----------
|
||||||
|
time=8157131
|
||||||
|
mem_heap_B=8
|
||||||
|
mem_heap_extra_B=16
|
||||||
|
mem_stacks_B=0
|
||||||
|
heap_tree=empty
|
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 23 KiB |
@ -0,0 +1,67 @@
|
|||||||
|
#include <unistd.h>
|
||||||
|
#include <fsvec.h>
|
||||||
|
#include <panic.h>
|
||||||
|
|
||||||
|
int fvec_new(fvec_t* restrict obj, const char* path)
|
||||||
|
{
|
||||||
|
obj->backing = fopen(path, "w+b");
|
||||||
|
if(!obj->backing) {
|
||||||
|
perror("fvec_new(): Failed to open file");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
obj->len=0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fvec_close(fvec_t* restrict obj)
|
||||||
|
{
|
||||||
|
if(obj->backing) fclose(obj->backing);
|
||||||
|
obj->backing=NULL;
|
||||||
|
obj->len=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fvec_pop_end(fvec_t* restrict obj, size_t sz)
|
||||||
|
{
|
||||||
|
if(!obj->len) return 0;
|
||||||
|
|
||||||
|
if(ftruncate(fileno(obj->backing), (obj->len-=sz))<0) {
|
||||||
|
perror("Failed to pop buffer");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fvec_push_whole_buffer(fvec_t* restrict obj, const void* _buffer, size_t sz)
|
||||||
|
{
|
||||||
|
size_t w= 0;
|
||||||
|
size_t c;
|
||||||
|
const unsigned char* buffer = _buffer;
|
||||||
|
while ( w<sz && (c=fwrite(buffer+w, 1, sz-w, obj->backing))>0 ) w+=c;
|
||||||
|
if(w!=sz) {
|
||||||
|
perror("Corrupted buffer state, aborting");
|
||||||
|
panic("Cannot continue");
|
||||||
|
}
|
||||||
|
obj->len += sz;
|
||||||
|
}
|
||||||
|
int fvec_get_whole_buffer(const fvec_t* restrict obj, void* _buffer, size_t _sz)
|
||||||
|
{
|
||||||
|
ssize_t sz = (ssize_t)_sz;
|
||||||
|
if(_sz != (size_t)sz) panic("Buffer size %lu too large", _sz);
|
||||||
|
|
||||||
|
if(obj->len<(size_t)sz) return 0;
|
||||||
|
if(fseek(obj->backing, -sz, SEEK_END)<0) {
|
||||||
|
perror("fvec_get_whole_buffer() failed to seek");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t w=0;
|
||||||
|
ssize_t c;
|
||||||
|
unsigned char* buffer = _buffer;
|
||||||
|
while ( w<_sz && (c=fread(buffer+w, 1, sz-w, obj->backing))>0 ) w+=c;
|
||||||
|
if (w!=_sz) {
|
||||||
|
perror("Corrupted buffer state, aborting");
|
||||||
|
panic("Cannot continue on FD %d (%p)", fileno(obj->backing), obj->backing);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include <fsvec.hpp>
|
||||||
|
#include <uuid.hpp>
|
||||||
|
#include <fsvec.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <tempfile.hpp>
|
||||||
|
|
||||||
|
#define FB file_back_buffer
|
||||||
|
|
||||||
|
|
||||||
|
struct FB::impl
|
||||||
|
{
|
||||||
|
size_t cap;
|
||||||
|
temp_file file;
|
||||||
|
|
||||||
|
fvec_t backing;
|
||||||
|
};
|
||||||
|
|
||||||
|
FB::FB(size_t cap) : inner(std::make_unique<FB::impl>())
|
||||||
|
{
|
||||||
|
// Set cap
|
||||||
|
inner->cap = cap;
|
||||||
|
// Create then open `inner->file`
|
||||||
|
if(!fvec_new(&inner->backing, inner->file->c_str())) panic("Failed to open backing for temp file buffer");
|
||||||
|
|
||||||
|
}
|
||||||
|
FB::FB(file_back_buffer&& m) : inner(std::move(m.inner)){}
|
||||||
|
FB::FB() : FB(DEFAULT_CAP){}
|
||||||
|
FB::~FB()
|
||||||
|
{
|
||||||
|
fvec_close(&inner->backing);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB::push_buf(byte* buf, size_t len)
|
||||||
|
{
|
||||||
|
fvec_push_whole_buffer(&inner->backing, (void*)buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FB::back(byte* buf, size_t len) const
|
||||||
|
{
|
||||||
|
return !!fvec_get_whole_buffer(&inner->backing, (void*)buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FB::pop_n(size_t len)
|
||||||
|
{
|
||||||
|
return !!fvec_pop_end(&inner->backing, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void _fb_run_tests()
|
||||||
|
{
|
||||||
|
fixed_spill_vector<int, 8> test;
|
||||||
|
int r0,r1=0;
|
||||||
|
for(int i=0;i<10;i++) {
|
||||||
|
D_dprintf("push: %d", (10-i));
|
||||||
|
test.push_back(10-i);
|
||||||
|
r1+= (10-i);
|
||||||
|
}
|
||||||
|
D_dprintf("r1: %d", r1);
|
||||||
|
r0=0;
|
||||||
|
while(test.size())
|
||||||
|
{
|
||||||
|
r0+=test.back();
|
||||||
|
D_dprintf("back: %d", test.back());
|
||||||
|
test.pop_back();
|
||||||
|
}
|
||||||
|
D_dprintf("r0: %d", r0);
|
||||||
|
|
||||||
|
if(r0!=r1) panic("fb failed test: %d, %d", r0, r1);
|
||||||
|
|
||||||
|
D_dprintf("test successful");
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <panic.h>
|
||||||
|
#include <map.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr inline auto MEMFD_DEFAULT_FLAGS = MFD_CLOEXEC;
|
||||||
|
int memfd_alloc(const char* name, size_t size = 0, int flags = MEMFD_DEFAULT_FLAGS)
|
||||||
|
{
|
||||||
|
int fd = memfd_create(name, flags);
|
||||||
|
if(fd < 0) panic("memfd_create() failed");
|
||||||
|
if(size)
|
||||||
|
if(ftruncate(fd, size)) { close(fd); panic("ftruncate() failed"); }
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace mm {
|
||||||
|
vmap::vmap()
|
||||||
|
: mmap(create_raw_fd(memfd_alloc(__PRETTY_FUNCTION__))) {}
|
||||||
|
vmap::vmap(size_t sz)
|
||||||
|
: mmap(create_raw_fd(memfd_alloc(__PRETTY_FUNCTION__, sz))) {}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int _can_allocate(size_t bytes)
|
||||||
|
{
|
||||||
|
void* shim = malloc(bytes);
|
||||||
|
if(shim) {
|
||||||
|
free(shim);
|
||||||
|
return 1;
|
||||||
|
} else return 0;
|
||||||
|
}
|
@ -1,18 +1,41 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include <panic.h>
|
#include <panic.h>
|
||||||
|
|
||||||
#include <colours.h>
|
#include <colours.h>
|
||||||
|
|
||||||
__attribute__((noreturn)) void _do_panic(struct panicinfo info, const char* fmt, ...)
|
#ifndef DEFAULT_PANIC_HANDLER
|
||||||
|
#if __cpp_exceptions || 1 /* XXX: Cannot detect this here */
|
||||||
|
# define DEFAULT_PANIC_HANDLER "_panic__start_unwind_cxx"
|
||||||
|
#else
|
||||||
|
# define DEFAULT_PANIC_HANDLER "_panic__start_unwind_abort"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern void _panic__start_unwind_cxx(void);
|
||||||
|
static void _panic__start_unwind_abort(void*)
|
||||||
|
__attribute__((weakref("abort"), noreturn));
|
||||||
|
|
||||||
|
static void _panic__start_unwind(void* payload)
|
||||||
|
__attribute__((noreturn, weakref(DEFAULT_PANIC_HANDLER)));
|
||||||
|
|
||||||
|
__attribute__((noreturn, weak)) void _do_panic(struct panicinfo info, const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list li;
|
va_list li;
|
||||||
va_start(li, fmt);
|
va_start(li, fmt);
|
||||||
fprintf(stderr, BOLD(UNDL(FRED("[!]"))) " (" BOLD("%s") "->" BOLD(FRED("%s")) ":" FYEL("%d") ") " BOLD(FRED("fatal error")) ": ", info.file, info.function, info.line);
|
#define FMT_TTY BOLD(UNDL(FRED("[!]"))) " (" BOLD("%s") "->" BOLD(FRED("%s")) ":" FYEL("%d") ") " BOLD(FRED("fatal error")) ": "
|
||||||
|
#define FMT_FIL "[!]" " (" "%s" "->" "%s" ":" "%d" ") " "fatal error" ": "
|
||||||
|
fprintf(stderr, isatty(fileno(stderr))
|
||||||
|
? FMT_TTY
|
||||||
|
: FMT_FIL , info.file, info.function, info.line);
|
||||||
vfprintf(stderr, fmt, li);
|
vfprintf(stderr, fmt, li);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
va_end(li);
|
va_end(li);
|
||||||
abort();
|
|
||||||
|
_panic__start_unwind(&info);
|
||||||
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
struct ErrorPayload {};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FatalError {
|
||||||
|
FatalError(void* payload)
|
||||||
|
: payload(payload) {}
|
||||||
|
FatalError(FatalError&& m)
|
||||||
|
: payload(std::exchange(m.payload, nullptr)) {}
|
||||||
|
|
||||||
|
FatalError& operator=(FatalError&& m)
|
||||||
|
{
|
||||||
|
if(this != &m) {
|
||||||
|
if(payload) destroy();
|
||||||
|
payload = std::exchange(m.payload, nullptr);
|
||||||
|
} return *this;
|
||||||
|
}
|
||||||
|
virtual ~FatalError() noexcept {
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
virtual void destroy() noexcept
|
||||||
|
{
|
||||||
|
/*if(auto* p = dynamic_cast<ErrorPayload*>(payload))
|
||||||
|
delete p;*/
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
void* payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
[[noreturn, gnu::weak]]
|
||||||
|
void _panic__start_unwind_cxx(void* payload)
|
||||||
|
{
|
||||||
|
#if __EXCEPTIONS
|
||||||
|
throw FatalError(payload);
|
||||||
|
#else
|
||||||
|
::abort();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,135 @@
|
|||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include <perc.h>
|
||||||
|
|
||||||
|
using fract_t = pr::Progress::fract_t;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using namespace pr;
|
||||||
|
size_t twidth(int fd = STDIN_FILENO, size_t orr = Progress::DEFAULT_WIDTH) noexcept
|
||||||
|
{
|
||||||
|
struct winsize w;
|
||||||
|
if(ioctl(fd, TIOCGWINSZ, &w) == -1) return orr;
|
||||||
|
return size_t(w.ws_col);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t def_bar_width(size_t tw) noexcept
|
||||||
|
{
|
||||||
|
return size_t(std::round(Progress::DEFAULT_TERM_FRACT * fract_t(tw)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace pr {
|
||||||
|
|
||||||
|
struct Progress::_impl {
|
||||||
|
Progress::fract_t fract; // 0..=1
|
||||||
|
FILE* output;
|
||||||
|
size_t width;
|
||||||
|
std::string aux;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t& Progress::width() noexcept { return inner_->width; }
|
||||||
|
size_t Progress::width() const noexcept { return inner_->width; }
|
||||||
|
|
||||||
|
fract_t& Progress::fraction() noexcept { return inner_->fract; }
|
||||||
|
fract_t Progress::fraction() const noexcept { return inner_->fract; }
|
||||||
|
|
||||||
|
fract_t Progress::percentage() const noexcept { return inner_->fract * 100.0l; }
|
||||||
|
void Progress::percentage(fract_t fract) noexcept { inner_->fract = fract / 100.0l; }
|
||||||
|
|
||||||
|
std::string& Progress::tag() noexcept { return inner_->aux; }
|
||||||
|
const std::string& Progress::tag() const noexcept { return inner_->aux; }
|
||||||
|
|
||||||
|
FILE* Progress::output() const noexcept { return inner_->output; }
|
||||||
|
FILE*& Progress::output() noexcept { return inner_->output; }
|
||||||
|
|
||||||
|
void Progress::render(bool flush) const noexcept
|
||||||
|
{
|
||||||
|
constinit thread_local static std::vector<char> buffer{};
|
||||||
|
|
||||||
|
const auto& inner = *inner_;
|
||||||
|
FILE* out = inner.output;
|
||||||
|
auto wf = fract_t(inner.width) * inner.fract;
|
||||||
|
auto perc = percentage();
|
||||||
|
size_t cf = size_t(std::floor(wf));
|
||||||
|
|
||||||
|
|
||||||
|
//auto print = []<typename F> (F f, auto&&... args) {
|
||||||
|
#define print(...) fmt::format_to(std::back_inserter(buffer), __VA_ARGS__);
|
||||||
|
//};
|
||||||
|
|
||||||
|
buffer.clear();
|
||||||
|
// Render bar
|
||||||
|
buffer.push_back('[');
|
||||||
|
for(size_t i=0;i<inner.width;i++)
|
||||||
|
if(i<=cf) buffer.push_back( '#' );
|
||||||
|
else buffer.push_back( ' ' );
|
||||||
|
buffer.push_back( ']' );
|
||||||
|
print(": {:00.2}%", perc);
|
||||||
|
if(inner.aux.size())
|
||||||
|
print(" ({})", std::string_view(inner.aux));
|
||||||
|
// Print bar
|
||||||
|
fprintf(out, "\r%.*s", int(buffer.size() & INT_MAX), static_cast<const char*>(buffer.data()));
|
||||||
|
// Flush output stream
|
||||||
|
if(flush) fflush(out);
|
||||||
|
#undef print
|
||||||
|
}
|
||||||
|
void Progress::spin(increment_t by, bool r, bool f) noexcept
|
||||||
|
{
|
||||||
|
auto& inner = *inner_;
|
||||||
|
inner.fract=by;
|
||||||
|
if(inner.fract > 1.0l)
|
||||||
|
inner.fract=1.0l;
|
||||||
|
if(r) this->render(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[gnu::nonnull(1)]]
|
||||||
|
Progress::Progress(FILE* p) noexcept
|
||||||
|
: inner_(std::make_unique<_impl>(0, p, def_bar_width(twidth(fileno(p))) )) {}
|
||||||
|
|
||||||
|
Progress::Progress(const Progress& p) noexcept
|
||||||
|
: inner_(p.inner_ ? std::make_unique<_impl>(*p.inner_) : nullptr) {}
|
||||||
|
|
||||||
|
Progress::Progress(Progress&& p) noexcept
|
||||||
|
: inner_(std::move(p.inner_)) {}
|
||||||
|
|
||||||
|
Progress& Progress::operator=(Progress&& p) noexcept
|
||||||
|
{
|
||||||
|
if(this != &p) inner_ = std::move(p.inner_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Progress& Progress::operator=(Progress const& p) noexcept
|
||||||
|
{
|
||||||
|
if(this != &p) inner_ = p.inner_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Progress::~Progress() {
|
||||||
|
if(inner_)
|
||||||
|
fputc('\n', inner_->output);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SPINNER
|
||||||
|
Spinner::~Spinner() {
|
||||||
|
//TODO: Add output: if(cur_) fputc('\n', output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Spinner::render(bool flush) {
|
||||||
|
/*char arr[] = {
|
||||||
|
'\r',
|
||||||
|
cur_,
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
fputs(arr, output);
|
||||||
|
if(flush) fflush(output);*/
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
TFILE=/tmp/shuffle3-test-$(uuidgen)
|
||||||
|
TFILE2=$TFILE-cmp
|
||||||
|
|
||||||
|
FSIZE=${FSIZE:-$(( 1024 * 1024 * 10))}
|
||||||
|
FCNT=${FCNT:-4}
|
||||||
|
|
||||||
|
TRUE_SIZE=$(( FSIZE * FCNT))
|
||||||
|
|
||||||
|
function cleanup {
|
||||||
|
rm -f $TFILE $TFILE2
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
stest() {
|
||||||
|
if fcmp $TFILE $TFILE2; then
|
||||||
|
echo ": shuffling $TRUE_SIZE bytes"
|
||||||
|
$1 -s $TFILE
|
||||||
|
if fcmp $TFILE $TFILE2; then
|
||||||
|
echo "Failed: Shuffle did nothing"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo ": unshuffling $TRUE_SIZE bytes"
|
||||||
|
$1 -u $TFILE
|
||||||
|
if fcmp $TFILE $TFILE2; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Failed: Unshuffle didn't reproduce original file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Invalid init: Files weren't identical"
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo ">>> Initialising"
|
||||||
|
dd if=/dev/urandom of=$TFILE bs=$FSIZE count=$FCNT >> /dev/null 2>&1 || exit -1
|
||||||
|
cp $TFILE $TFILE2 || exit -1
|
||||||
|
|
||||||
|
for ex in "$@"; do
|
||||||
|
if [[ -f "${ex%% *}" ]] || command -v "${ex%% *}" >/dev/null 2>&1; then
|
||||||
|
echo ">>> Testing $ex"
|
||||||
|
stest "$ex" || exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Passed."
|