// -- io helpers --
+// Forward declare all the I/O helpers so strict ADL can find them in
+// the case of containers of containers. I'm tempted to abstract this
+// stuff using template templates like I did for denc.
+
+template<class A, class B>
+inline ostream& operator<<(ostream&out, const pair<A,B>& v);
+template<class A, class Alloc>
+inline ostream& operator<<(ostream& out, const vector<A,Alloc>& v);
+template<class A, class Comp, class Alloc>
+inline ostream& operator<<(ostream& out, const deque<A,Alloc>& v);
+template<class A, class B, class C>
+inline ostream& operator<<(ostream&out, const boost::tuple<A, B, C> &t);
+template<class A, class Alloc>
+inline ostream& operator<<(ostream& out, const list<A,Alloc>& ilist);
+template<class A, class Comp, class Alloc>
+inline ostream& operator<<(ostream& out, const set<A, Comp, Alloc>& iset);
+template<class A, class Comp, class Alloc>
+inline ostream& operator<<(ostream& out, const multiset<A,Comp,Alloc>& iset);
+template<class A, class B, class Comp, class Alloc>
+inline ostream& operator<<(ostream& out, const map<A,B,Comp,Alloc>& m);
+template<class A, class B, class Comp, class Alloc>
+inline ostream& operator<<(ostream& out, const multimap<A,B,Comp,Alloc>& m);
+
template<class A, class B>
inline ostream& operator<<(ostream& out, const pair<A,B>& v) {
return out << v.first << "," << v.second;
// --
-struct prettybyte_t {
- uint64_t v;
- // cppcheck-suppress noExplicitConstructor
- prettybyte_t(uint64_t _v) : v(_v) {}
-};
-
-inline ostream& operator<<(ostream& out, const prettybyte_t& b)
-{
- uint64_t bump_after = 100;
- if (b.v > bump_after << 60)
- return out << (b.v >> 60) << " EB";
- if (b.v > bump_after << 50)
- return out << (b.v >> 50) << " PB";
- if (b.v > bump_after << 40)
- return out << (b.v >> 40) << " TB";
- if (b.v > bump_after << 30)
- return out << (b.v >> 30) << " GB";
- if (b.v > bump_after << 20)
- return out << (b.v >> 20) << " MB";
- if (b.v > bump_after << 10)
- return out << (b.v >> 10) << " kB";
- return out << b.v << " bytes";
+namespace {
+ inline ostream& format_u(ostream& out, const uint64_t v, const uint64_t n,
+ const int index, const uint64_t mult, const char* u)
+ {
+ char buffer[32];
+
+ if (index == 0) {
+ (void) snprintf(buffer, sizeof(buffer), "%" PRId64 "%s", n, u);
+ } else if ((v % mult) == 0) {
+ // If this is an even multiple of the base, always display
+ // without any decimal fraction.
+ (void) snprintf(buffer, sizeof(buffer), "%" PRId64 "%s", n, u);
+ } else {
+ // We want to choose a precision that reflects the best choice
+ // for fitting in 5 characters. This can get rather tricky when
+ // we have numbers that are very close to an order of magnitude.
+ // For example, when displaying 10239 (which is really 9.999K),
+ // we want only a single place of precision for 10.0K. We could
+ // develop some complex heuristics for this, but it's much
+ // easier just to try each combination in turn.
+ int i;
+ for (i = 2; i >= 0; i--) {
+ if (snprintf(buffer, sizeof(buffer), "%.*f%s", i,
+ static_cast<double>(v) / mult, u) <= 7)
+ break;
+ }
+ }
+
+ return out << buffer;
+ }
}
-struct si_t {
+/*
+ * Use this struct to pretty print values that should be formatted with a
+ * decimal unit prefix (the classic SI units). No actual unit will be added.
+ */
+struct si_u_t {
uint64_t v;
- // cppcheck-suppress noExplicitConstructor
- si_t(uint64_t _v) : v(_v) {}
+ explicit si_u_t(uint64_t _v) : v(_v) {};
};
-inline ostream& operator<<(ostream& out, const si_t& b)
+inline ostream& operator<<(ostream& out, const si_u_t& b)
{
- uint64_t bump_after = 100;
- if (b.v > bump_after << 60)
- return out << (b.v >> 60) << "E";
- if (b.v > bump_after << 50)
- return out << (b.v >> 50) << "P";
- if (b.v > bump_after << 40)
- return out << (b.v >> 40) << "T";
- if (b.v > bump_after << 30)
- return out << (b.v >> 30) << "G";
- if (b.v > bump_after << 20)
- return out << (b.v >> 20) << "M";
- if (b.v > bump_after << 10)
- return out << (b.v >> 10) << "k";
- return out << b.v;
+ uint64_t n = b.v;
+ int index = 0;
+ uint64_t mult = 1;
+ const char* u[] = {"", "k", "M", "G", "T", "P", "E"};
+
+ while (n >= 1000 && index < 7) {
+ n /= 1000;
+ index++;
+ mult *= 1000;
+ }
+
+ return format_u(out, b.v, n, index, mult, u[index]);
}
-struct pretty_si_t {
+/*
+ * Use this struct to pretty print values that should be formatted with a
+ * binary unit prefix (IEC units). Since binary unit prefixes are to be used for
+ * "multiples of units in data processing, data transmission, and digital
+ * information" (so bits and bytes) and so far bits are not printed, the unit
+ * "B" for "byte" is added besides the multiplier.
+ */
+struct byte_u_t {
uint64_t v;
- // cppcheck-suppress noExplicitConstructor
- pretty_si_t(uint64_t _v) : v(_v) {}
+ explicit byte_u_t(uint64_t _v) : v(_v) {};
};
-inline ostream& operator<<(ostream& out, const pretty_si_t& b)
+inline ostream& operator<<(ostream& out, const byte_u_t& b)
{
- uint64_t bump_after = 100;
- if (b.v > bump_after << 60)
- return out << (b.v >> 60) << " E";
- if (b.v > bump_after << 50)
- return out << (b.v >> 50) << " P";
- if (b.v > bump_after << 40)
- return out << (b.v >> 40) << " T";
- if (b.v > bump_after << 30)
- return out << (b.v >> 30) << " G";
- if (b.v > bump_after << 20)
- return out << (b.v >> 20) << " M";
- if (b.v > bump_after << 10)
- return out << (b.v >> 10) << " k";
- return out << b.v << " ";
-}
+ uint64_t n = b.v;
+ int index = 0;
+ const char* u[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"};
-struct kb_t {
- uint64_t v;
- // cppcheck-suppress noExplicitConstructor
- kb_t(uint64_t _v) : v(_v) {}
-};
+ while (n >= 1024 && index < 7) {
+ n /= 1024;
+ index++;
+ }
-inline ostream& operator<<(ostream& out, const kb_t& kb)
-{
- uint64_t bump_after = 100;
- if (kb.v > bump_after << 40)
- return out << (kb.v >> 40) << " PB";
- if (kb.v > bump_after << 30)
- return out << (kb.v >> 30) << " TB";
- if (kb.v > bump_after << 20)
- return out << (kb.v >> 20) << " GB";
- if (kb.v > bump_after << 10)
- return out << (kb.v >> 10) << " MB";
- return out << kb.v << " kB";
+ return format_u(out, b.v, n, index, 1ULL << (10 * index), u[index]);
}
inline ostream& operator<<(ostream& out, const ceph_mon_subscribe_item& i)
<< ((i.flags & CEPH_SUBSCRIBE_ONETIME) ? "" : "+");
}
-enum health_status_t {
- HEALTH_ERR = 0,
- HEALTH_WARN = 1,
- HEALTH_OK = 2,
-};
-
-#ifdef __cplusplus
-inline ostream& operator<<(ostream &oss, health_status_t status) {
- switch (status) {
- case HEALTH_ERR:
- oss << "HEALTH_ERR";
- break;
- case HEALTH_WARN:
- oss << "HEALTH_WARN";
- break;
- case HEALTH_OK:
- oss << "HEALTH_OK";
- break;
- }
- return oss;
-}
-#endif
-
struct weightf_t {
float v;
// cppcheck-suppress noExplicitConstructor
WRITE_CMP_OPERATORS_1(shard_id_t, id)
ostream &operator<<(ostream &lhs, const shard_id_t &rhs);
-#if defined(__sun) || defined(_AIX) || defined(DARWIN)
-__s32 ceph_to_host_errno(__s32 e);
+#if defined(__sun) || defined(_AIX) || defined(DARWIN) || defined(__FreeBSD__)
+__s32 ceph_to_hostos_errno(__s32 e);
+__s32 hostos_to_ceph_errno(__s32 e);
#else
-#define ceph_to_host_errno(e) (e)
+#define ceph_to_hostos_errno(e) (e)
+#define hostos_to_ceph_errno(e) (e)
#endif
struct errorcode32_t {
// cppcheck-suppress noExplicitConstructor
errorcode32_t(int32_t i) : code(i) {}
- operator int() const { return code; }
- int operator==(int i) {
- return code==i;
- }
+ operator int() const { return code; }
+ int* operator&() { return &code; }
+ int operator==(int i) { return code == i; }
+ int operator>(int i) { return code > i; }
+ int operator>=(int i) { return code >= i; }
+ int operator<(int i) { return code < i; }
+ int operator<=(int i) { return code <= i; }
void encode(bufferlist &bl) const {
- ::encode(code, bl);
+ __s32 newcode = hostos_to_ceph_errno(code);
+ ::encode(newcode, bl);
}
void decode(bufferlist::iterator &bl) {
::decode(code, bl);
- code = ceph_to_host_errno(code);
+ code = ceph_to_hostos_errno(code);
}
};
WRITE_CLASS_ENCODER(errorcode32_t)