-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutils.h
108 lines (94 loc) · 2.31 KB
/
utils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//(c) 2016 by Authors
//This file is a part of ABruijn program.
//Released under the BSD license (see LICENSE file)
#pragma once
#include <vector>
#include <algorithm>
#include <sstream>
#include <execinfo.h>
#include "logger.h"
template<class T>
void vecRemove(std::vector<T>& v, T val)
{
v.erase(std::remove(v.begin(), v.end(), val), v.end());
}
struct pairhash
{
public:
template <typename T, typename U>
std::size_t operator()(const std::pair<T, U> &x) const
{
return std::hash<T>()(x.first) ^ std::hash<U>()(x.second);
}
};
template<typename T>
T quantile(const std::vector<T>& vec, int percent)
{
if (vec.empty()) return 0;
//NOTE: there's a bug in libstdc++ nth_element,
//that sometimes leads to a segfault. This is why
//we have this inefficient impleemntation here
//std::nth_element(vec.begin(), vec.begin() + vec.size() / 2,
// vec.end());
auto sortedVec = vec;
std::sort(sortedVec.begin(), sortedVec.end());
size_t targetId = std::min(vec.size() * (size_t)percent / 100,
vec.size() - 1);
return sortedVec[targetId];
}
template<typename T>
T median(const std::vector<T>& vec)
{
return quantile(vec, 50);
}
inline std::vector<std::string>
splitString(const std::string &s, char delim)
{
std::vector<std::string> elems;
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) elems.push_back(item);
return elems;
}
inline bool fileExists(const std::string& path)
{
std::ifstream fin(path);
return fin.good();
}
inline void segfaultHandler(int signal __attribute__((unused)))
{
void *stackArray[20];
size_t size = backtrace(stackArray, 10);
Logger::get().error() << "Segmentation fault! Backtrace:";
char** backtrace = backtrace_symbols(stackArray, size);
for (size_t i = 0; i < size; ++i)
{
Logger::get().error() << "\t" << backtrace[i];
}
abort();
}
inline void exceptionHandler()
{
static bool triedThrow = false;
try
{
if (!triedThrow)
{
triedThrow = true;
throw;
}
}
catch (const std::exception &e)
{
Logger::get().error() << "Caught unhandled exception: " << e.what();
}
catch (...) {}
void *stackArray[20];
size_t size = backtrace(stackArray, 10);
char** backtrace = backtrace_symbols(stackArray, size);
for (size_t i = 0; i < size; ++i)
{
Logger::get().error() << "\t" << backtrace[i];
}
abort();
}