zeek/src/probabilistic/CounterVector.h
Robin Sommer 01e662b3e0 Reimplement serialization infrastructure for OpaqueVals.
We need this to sender through Broker, and we also leverage it for
cloning opaques. The serialization methods now produce Broker data
instances directly, and no longer go through the binary formatter.

Summary of the new API for types derived from OpaqueVal:

    - Add DECLARE_OPAQUE_VALUE(<class>) to the class declaration
    - Add IMPLEMENT_OPAQUE_VALUE(<class>) to the class' implementation file
    - Implement these two methods (which are declated by the 1st macro):
        - broker::data DoSerialize() const
        - bool DoUnserialize(const broker::data& data)

This machinery should work correctly from dynamic plugins as well.

OpaqueVal provides a default implementation of DoClone() as well that
goes through serialization. Derived classes can provide a more
efficient version if they want.

The declaration of the "OpaqueVal" class has moved into the header
file "OpaqueVal.h", along with the new serialization infrastructure.
This is breaking existing code that relies on the location, but
because the API is changing anyways that seems fine.

This adds an internal BiF
"Broker::__opaque_clone_through_serialization" that does what the name
says: deep-copying an opaque by serializing, then-deserializing. That
can be used to tests the new functionality from btests.

Not quite done yet. TODO:
    - Not all tests pass yet:
        [  0%] language.named-set-ctors ... failed
        [ 16%] language.copy-all-opaques ... failed
        [ 33%] language.set-type-checking ... failed
        [ 50%] language.table-init-container-ctors ... failed
        [ 66%] coverage.sphinx-zeekygen-docs ... failed
        [ 83%] scripts.base.frameworks.sumstats.basic-cluster ... failed

      (Some of the serialization may still be buggy.)

    - Clean up the code a bit more.
2019-06-17 16:13:54 +00:00

157 lines
3.2 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#ifndef PROBABILISTIC_COUNTERVECTOR_H
#define PROBABILISTIC_COUNTERVECTOR_H
#include <cstddef>
#include <cstdint>
#include <broker/Data.h>
namespace probabilistic {
class BitVector;
/**
* A vector of counters, each of which has a fixed number of bits.
*/
class CounterVector {
public:
typedef size_t size_type;
typedef uint64_t count_type;
/**
* Constructs a counter vector having cells of a given width.
*
* @param width The number of bits that each cell occupies.
*
* @param cells The number of cells in the bitvector.
*
* @pre `cells > 0 && width > 0`
*/
explicit CounterVector(size_t width, size_t cells = 1024);
/**
* Copy-constructs a counter vector.
*
* @param other The counter vector to copy.
*/
CounterVector(const CounterVector& other);
/**
* Destructor.
*/
virtual ~CounterVector();
/**
* Increments a given cell.
*
* @param cell The cell to increment.
*
* @param value The value to add to the current counter in *cell*.
*
* @return `true` if adding *value* to the counter in *cell* succeeded.
*
* @pre `cell < Size()`
*/
bool Increment(size_type cell, count_type value = 1);
/**
* Decrements a given cell.
*
* @param cell The cell to decrement.
*
* @param value The value to subtract from the current counter in *cell*.
*
* @return `true` if subtracting *value* from the counter in *cell* succeeded.
*
* @pre `cell < Size()`
*/
bool Decrement(size_type cell, count_type value = 1);
/**
* Retrieves the counter of a given cell.
*
* @param cell The cell index to retrieve the count for.
*
* @return The counter associated with *cell*.
*
* @pre `cell < Size()`
*/
count_type Count(size_type cell) const;
/**
* Checks whether all counters are 0.
* @return `true` iff all counters have the value 0.
*/
bool AllZero() const;
/**
* Sets all counters to 0.
*/
void Reset();
/**
* Retrieves the number of cells in the storage.
*
* @return The number of cells.
*/
size_type Size() const;
/**
* Retrieves the counter width.
*
* @return The number of bits per counter.
*/
size_t Width() const;
/**
* Computes the maximum counter value.
*
* @return The maximum counter value based on the width.
*/
size_t Max() const;
/**
* Merges another counter vector into this instance by *adding* the
* counters of each cells.
*
* @param other The counter vector to merge into this instance.
*
* @return A reference to `*this`.
*
* @pre `Size() == other.Size() && Width() == other.Width()`
*/
CounterVector& Merge(const CounterVector& other);
/**
* An alias for ::Merge.
*/
CounterVector& operator|=(const CounterVector& other);
/** Computes a hash value of the internal representation.
* This is mainly for debugging/testing purposes.
*
* @return The hash.
*/
uint64_t Hash() const;
broker::expected<broker::data> Serialize() const;
static std::unique_ptr<CounterVector> Unserialize(const broker::data& data);
protected:
friend CounterVector operator|(const CounterVector& x,
const CounterVector& y);
CounterVector() { }
private:
CounterVector& operator=(const CounterVector&); // Disable.
BitVector* bits;
size_t width;
};
}
#endif