diff --git a/src/HyperLogLog.h b/src/HyperLogLog.h index 81c19067a1..34a2afd9b7 100644 --- a/src/HyperLogLog.h +++ b/src/HyperLogLog.h @@ -10,7 +10,10 @@ */ #define conf .95 +class CardinalityVal; + class CardinalityCounter { + friend class CardinalityVal; private: /* diff --git a/src/OpaqueVal.cc b/src/OpaqueVal.cc index 604ce2938e..d1d97c1f8c 100644 --- a/src/OpaqueVal.cc +++ b/src/OpaqueVal.cc @@ -1,9 +1,10 @@ #include "OpaqueVal.h" #include "Reporter.h" #include "Serializer.h" +#include "HyperLogLog.h" -CardinalityVal::CardinalityVal() +CardinalityVal::CardinalityVal() : OpaqueVal(new OpaqueType("cardinality")) { valid = false; } @@ -14,6 +15,49 @@ CardinalityVal::~CardinalityVal() delete c; } +IMPLEMENT_SERIAL(CardinalityVal, SER_CARDINALITY_VAL); + +bool CardinalityVal::DoSerialize(SerialInfo* info) const + { + DO_SERIALIZE(SER_CARDINALITY_VAL, OpaqueVal); + + if ( ! IsValid() ) + return true; + + assert(c); + + bool valid = true; + + valid &= SERIALIZE(c->m); + for ( int i = 0; i < c->m; i++ ) + { + valid &= SERIALIZE(c->buckets[i]); + } + + return valid; + } + +bool CardinalityVal::DoUnserialize(UnserialInfo* info) + { + DO_UNSERIALIZE(OpaqueVal); + + if ( ! IsValid() ) + return true; + + uint64_t m; + bool valid = UNSERIALIZE(&m); + + c = new CardinalityCounter(m); + uint8_t* buckets = c->buckets; + for ( int i = 0; i < m; i++ ) + { + uint8_t* currbucket = buckets + i; + valid &= UNSERIALIZE( currbucket ); + } + + return valid; + } + bool CardinalityVal::Init(CardinalityCounter* arg_c) { if ( valid ) diff --git a/src/OpaqueVal.h b/src/OpaqueVal.h index 01f86529c7..1bdd842cad 100644 --- a/src/OpaqueVal.h +++ b/src/OpaqueVal.h @@ -11,17 +11,17 @@ class CardinalityCounter; class CardinalityVal: public OpaqueVal { public: - CardinalityVal(); - ~CardinalityVal(); bool Init(CardinalityCounter*); bool IsValid() const { return valid; }; CardinalityCounter* Get() { return c; }; + CardinalityVal(); + ~CardinalityVal(); private: bool valid; CardinalityCounter* c; -// DECLARE_SERIAL(CardinalityVal); Fixme? + DECLARE_SERIAL(CardinalityVal); }; diff --git a/src/SerialTypes.h b/src/SerialTypes.h index 723badab1e..56a1c5e8dd 100644 --- a/src/SerialTypes.h +++ b/src/SerialTypes.h @@ -104,6 +104,7 @@ SERIAL_VAL(MD5_VAL, 16) SERIAL_VAL(SHA1_VAL, 17) SERIAL_VAL(SHA256_VAL, 18) SERIAL_VAL(ENTROPY_VAL, 19) +SERIAL_VAL(CARDINALITY_VAL, 20) #define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR) SERIAL_EXPR(EXPR, 1) diff --git a/src/SerializationFormat.cc b/src/SerializationFormat.cc index 10dd4f29ea..271163d5db 100644 --- a/src/SerializationFormat.cc +++ b/src/SerializationFormat.cc @@ -107,6 +107,16 @@ bool BinarySerializationFormat::Read(int* v, const char* tag) return true; } +bool BinarySerializationFormat::Read(uint8* v, const char* tag) + { + if ( ! ReadData(v, sizeof(*v)) ) + return false; + + *v = ntohs(*v); + DBG_LOG(DBG_SERIAL, "Read uint8 %hu [%s]", *v, tag); + return true; + } + bool BinarySerializationFormat::Read(uint16* v, const char* tag) { if ( ! ReadData(v, sizeof(*v)) ) @@ -301,6 +311,13 @@ bool BinarySerializationFormat::Write(char v, const char* tag) return WriteData(&v, 1); } +bool BinarySerializationFormat::Write(uint8 v, const char* tag) + { + DBG_LOG(DBG_SERIAL, "Write uint8 %hu [%s]", v, tag); + v = htons(v); + return WriteData(&v, sizeof(v)); + } + bool BinarySerializationFormat::Write(uint16 v, const char* tag) { DBG_LOG(DBG_SERIAL, "Write uint16 %hu [%s]", v, tag); @@ -447,6 +464,12 @@ bool XMLSerializationFormat::Read(int* v, const char* tag) return false; } +bool XMLSerializationFormat::Read(uint8* v, const char* tag) + { + reporter->InternalError("no reading of xml"); + return false; + } + bool XMLSerializationFormat::Read(uint16* v, const char* tag) { reporter->InternalError("no reading of xml"); @@ -530,6 +553,13 @@ bool XMLSerializationFormat::Write(char v, const char* tag) return WriteElem(tag, "char", &v, 1); } +bool XMLSerializationFormat::Write(uint8 v, const char* tag) + { + const char* tmp = fmt("%" PRIu8, v); + return WriteElem(tag, "uint8", tmp, strlen(tmp)); + } + + bool XMLSerializationFormat::Write(uint16 v, const char* tag) { const char* tmp = fmt("%" PRIu16, v); diff --git a/src/SerializationFormat.h b/src/SerializationFormat.h index f270b61bae..05cf56d961 100644 --- a/src/SerializationFormat.h +++ b/src/SerializationFormat.h @@ -23,6 +23,7 @@ public: virtual void EndRead(); virtual bool Read(int* v, const char* tag) = 0; + virtual bool Read(uint8* v, const char* tag) = 0; virtual bool Read(uint16* v, const char* tag) = 0; virtual bool Read(uint32* v, const char* tag) = 0; virtual bool Read(int64* v, const char* tag) = 0; @@ -47,6 +48,7 @@ public: virtual uint32 EndWrite(char** data); // passes ownership virtual bool Write(int v, const char* tag) = 0; + virtual bool Write(uint8 v, const char* tag) = 0; virtual bool Write(uint16 v, const char* tag) = 0; virtual bool Write(uint32 v, const char* tag) = 0; virtual bool Write(int64 v, const char* tag) = 0; @@ -92,6 +94,7 @@ public: virtual ~BinarySerializationFormat(); virtual bool Read(int* v, const char* tag); + virtual bool Read(uint8* v, const char* tag); virtual bool Read(uint16* v, const char* tag); virtual bool Read(uint32* v, const char* tag); virtual bool Read(int64* v, const char* tag); @@ -106,6 +109,7 @@ public: virtual bool Read(struct in_addr* addr, const char* tag); virtual bool Read(struct in6_addr* addr, const char* tag); virtual bool Write(int v, const char* tag); + virtual bool Write(uint8 v, const char* tag); virtual bool Write(uint16 v, const char* tag); virtual bool Write(uint32 v, const char* tag); virtual bool Write(int64 v, const char* tag); @@ -132,6 +136,7 @@ public: // We don't write anything if tag is nil. virtual bool Write(int v, const char* tag); + virtual bool Write(uint8 v, const char* tag); virtual bool Write(uint16 v, const char* tag); virtual bool Write(uint32 v, const char* tag); virtual bool Write(int64 v, const char* tag); @@ -152,6 +157,7 @@ public: // Not implemented. virtual bool Read(int* v, const char* tag); + virtual bool Read(uint8* v, const char* tag); virtual bool Read(uint16* v, const char* tag); virtual bool Read(uint32* v, const char* tag); virtual bool Read(int64* v, const char* tag); diff --git a/src/Serializer.h b/src/Serializer.h index 72e0723880..719d4dc527 100644 --- a/src/Serializer.h +++ b/src/Serializer.h @@ -54,6 +54,7 @@ public: DECLARE_WRITE(type) DECLARE_IO(int) + DECLARE_IO(uint8) DECLARE_IO(uint16) DECLARE_IO(uint32) DECLARE_IO(int64)