1 // -*- mode: c++; c-basic-offset: 4 -*-
2 #ifndef CLICK_RANDOMSAMPLE_HH
3 #define CLICK_RANDOMSAMPLE_HH
4 #include <click/element.hh>
5 #include <click/atomic.hh>
6 CLICK_DECLS
7 
8 /*
9  * =c
10  *
11  * RandomSample([P, I<KEYWORDS>])
12  *
13  * =s classification
14  *
15  * samples packets with some probability
16  *
17  * =d
18  *
19  * Samples packets with probability P. One out of 1/P packets are sent to the
20  * first output. The remaining packets are dropped, unless the element has two
21  * outputs, in which case they are emitted on output 1.
22  *
23  * If you don't specify P, you must supply one of the SAMPLE and DROP keyword
24  * arguments.
25  *
26  * Keyword arguments are:
27  *
28  * =over 8
29  *
30  * =item SAMPLE I<P>
31  *
32  * Sets the sampling probability to I<P>.
33  *
34  * =item DROP I<Q>
35  *
36  * The element will drop packets with probability I<Q>. Same as suppling (1 -
37  * I<Q>) as the sampling probability.
38  *
39  * =item ACTIVE
40  *
41  * Boolean. RandomSample is active or inactive; when inactive, it sends all
42  * packets to output 0. Default is true (active).
43  *
44  * =back
45  *
46  * =h sampling_prob read/write
47  *
48  * Returns or sets the sampling probability.
49  *
50  * =h drop_prob read/write
51  *
52  * Returns or sets the drop probability, which is 1 minus the sampling
53  * probability.
54  *
55  * =h active read/write
56  *
57  * Makes the element active or inactive.
58  *
59  * =h drops read-only
60  *
61  * Returns the number of packets dropped.
62  *
63  * =a RandomBitErrors */
64 
65 class RandomSample : public Element { public:
66 
67     RandomSample() CLICK_COLD;
68 
class_name() const69     const char *class_name() const		{ return "RandomSample"; }
port_count() const70     const char *port_count() const		{ return PORTS_1_1X2; }
processing() const71     const char *processing() const		{ return PROCESSING_A_AH; }
72 
73     int configure(Vector<String> &, ErrorHandler *) CLICK_COLD;
74     int initialize(ErrorHandler *) CLICK_COLD;
can_live_reconfigure() const75     bool can_live_reconfigure() const		{ return true; }
76     void add_handlers() CLICK_COLD;
77 
78     void push(int port, Packet *);
79     Packet *pull(int port);
80 
81   private:
82 
83     enum { SAMPLING_SHIFT = 28 };
84     enum { SAMPLING_MASK = (1 << SAMPLING_SHIFT) - 1 };
85 
86     enum { h_sample, h_drop, h_config };
87 
88     uint32_t _sampling_prob;		// out of (1<<SAMPLING_SHIFT)
89     bool _active;
90     atomic_uint32_t _drops;
91 
92     static String read_handler(Element *, void *) CLICK_COLD;
93     static int write_handler(const String &, Element *, void *, ErrorHandler *) CLICK_COLD;
94 };
95 
96 CLICK_ENDDECLS
97 #endif
98