#ifndef CLICK_AGGREGATELAST_HH #define CLICK_AGGREGATELAST_HH #include #include #include "aggregatenotifier.hh" CLICK_DECLS /* =c AggregateLast([I]) =s aggregates lets through last packet per aggregate annotation =d AggregateLast forwards only the final packet with a given aggregate annotation value. All previous packets with that aggregate annotation are emitted on the second output, if it exists, or dropped if it does not. The output packet will have EXTRA_PACKETS_ANNO, EXTRA_LENGTH_ANNO, and FIRST_TIMESTAMP_ANNO set to the values reflecting the total volume of the aggregate. Keyword arguments are: =over 8 =item NOTIFIER The name of an AggregateNotifier element, like AggregateIPFlows. If given, then AggregateLast will output a packet when the AggregateNotifier informs it that the packet's aggregate is complete. This can save significant memory on long traces. =item STOP_AFTER_CLEAR Boolean. If true, then stop the router after the 'clear' handler is called and completes. Default is false. =back =h clear write-only When written, AggregateLast will output every packet it has stored and clear its tables. This is the only time AggregateLast will emit packets if NOTIFIER was not set. =n AggregateFirst forwards the the first packet with a given aggregate annotation value, rather than the last packet. It has significantly smaller memory requirements than AggregateLast. Only available in user-level processes. =a AggregateFirst, AggregateIP, AggregateIPFlows, AggregateCounter, AggregateFilter */ class AggregateLast : public Element, public AggregateListener { public: AggregateLast(); ~AggregateLast(); const char *class_name() const { return "AggregateLast"; } const char *port_count() const { return "1/1-2"; } const char *processing() const { return PUSH; } int configure(Vector &, ErrorHandler *); int initialize(ErrorHandler *); void cleanup(CleanupStage); void push(int, Packet *); bool run_task(); void aggregate_notify(uint32_t, AggregateEvent, const Packet *); void add_handlers(); private: enum { ROW_BITS = 10, ROW_SHIFT = 0, NROW = 1<> PLANE_SHIFT) & PLANE_MASK]) if (Packet **c = p[(agg >> COL_SHIFT) & COL_MASK]) return c; return create_row(agg); } CLICK_ENDDECLS #endif