00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #if !defined(_SOURCE_H_INCLUDED_)
00013 #define _SOURCE_H_INCLUDED_
00014
00015
00016
00017 #include "_types.h"
00018 #include "_rand_MT.h"
00019 #include "_link.h"
00020 #include "trace.h"
00021
00022 const int16u MIN_BURST = 1;
00023 const DOUBLE MIN_ALPHA = 1.0;
00024 const DOUBLE MAX_ALPHA = 2.0;
00025
00026 template < class T > inline void SetInRange( T& x, T y, T z ) { if( x <= y || x >= z ) x = (y + z) / 2; }
00027
00029 class Source : public DLinkable
00030 {
00031 private:
00032 int16u ID;
00033 int16u Priority;
00034 bytestamp_t Elapsed;
00035
00036 protected:
00037 pct_size_t PctSize;
00038 pct_size_t Preamble;
00039 pct_size_t PctSpace;
00040 int32u BurstSize;
00041
00042 virtual inline int32u GetBurstSize(void) = 0;
00043 virtual inline bytestamp_t GetGapSize(void) = 0;
00044
00045 inline bytestamp_t SetGap( bytestamp_t gap ) { return gap < Preamble? Preamble : gap; }
00046
00047 public:
00048
00049 Source( int16u id, int16u prior, pct_size_t pct_sz, pct_size_t preamble ) : DLinkable()
00050 {
00051 ID = id;
00052 Priority = prior;
00053 PctSize = pct_sz;
00054 Preamble = preamble;
00055 PctSpace = PctSize + Preamble;
00056 }
00057
00058 virtual ~Source() {}
00059
00061
00062 inline void Reset(void)
00063 {
00064
00065 bytestamp_t burst_size = GetBurstSize() * PctSpace;
00066 bytestamp_t period = burst_size + GetGapSize();
00067 bytestamp_t start_time = _uniform_real_( 0, period );
00068
00069
00070
00071
00072 if( start_time > burst_size )
00073 {
00074 BurstSize = GetBurstSize();
00075 Elapsed = period - start_time;
00076 }
00077 else
00078 {
00079 BurstSize = (int32s)( ( burst_size - start_time )/PctSpace + 1 );
00080 Elapsed = 0.0;
00081 }
00082 }
00084 virtual inline void SetLoad( DOUBLE load ) = 0;
00085
00086 inline bytestamp_t GetID(void) { return ID; }
00087 inline bytestamp_t GetPriority(void) { return Priority; }
00088 inline bytestamp_t GetArrival(void) { return Elapsed; }
00089 inline pct_size_t GetPctSize(void) { return PctSize; }
00090 inline Trace GetTrace(void) { return Trace( ID, Priority, Elapsed, PctSize ); }
00091 inline void GetTrace( Trace& trc ) { trc.SourceID = ID;
00092 trc.QueueID = Priority;
00093 trc.ByteStamp = Elapsed;
00094 trc.PacketSize = PctSize;
00095 }
00096
00098
00099
00100
00101
00102
00103
00104
00106 inline void ExtractPacket(Trace& trc)
00107 {
00108 GetTrace( trc );
00109 ExtractPacket();
00110 }
00112 inline void ExtractPacket(void)
00113 {
00114 if( BurstSize == 0 )
00115 {
00116 BurstSize = GetBurstSize();
00117
00118
00119
00120 Elapsed += GetGapSize();
00121
00122 }
00123 BurstSize--;
00124 Elapsed += PctSpace;
00125
00126 }
00128 };
00129
00131 class SourcePareto : public Source
00132 {
00133 private:
00134 bytestamp_t MinGap;
00135 DOUBLE ONShape;
00136 DOUBLE OFFShape;
00137
00138 virtual inline int32u GetBurstSize(void) { return round<int32u>(_pareto_(ONShape) * MIN_BURST); }
00139 virtual inline bytestamp_t GetGapSize(void) { return _pareto_(OFFShape) * MinGap; }
00140
00141 public:
00142
00143 SourcePareto( int16u id,
00144 int16u prior,
00145 pct_size_t pct_sz,
00146 pct_size_t preamble,
00147 DOUBLE load,
00148 DOUBLE on_shape,
00149 DOUBLE off_shape ) : Source( id, prior, pct_sz, preamble )
00150 {
00151 ONShape = on_shape;
00152 OFFShape = off_shape;
00153
00154 SetInRange<DOUBLE>( ONShape, MIN_ALPHA, MAX_ALPHA );
00155 SetInRange<DOUBLE>( OFFShape, MIN_ALPHA, MAX_ALPHA );
00156
00157 SetLoad( load );
00158 Reset();
00159 }
00160 virtual ~SourcePareto() {}
00162 virtual inline void SetLoad( DOUBLE load )
00163 {
00164 SetInRange<DOUBLE>( load, 0.0, 1.0 );
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 DOUBLE on_coef = (1.0 - pow(SMALL_VAL, 1.0 - 1.0/ONShape)) / (1.0 - 1.0/ONShape);
00183 DOUBLE off_coef = (1.0 - pow(SMALL_VAL, 1.0 - 1.0/OFFShape)) / (1.0 - 1.0/OFFShape);
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 MinGap = SetGap((on_coef/off_coef) * MIN_BURST * (PctSize/load - PctSpace));
00205
00206 }
00207 };
00208
00210 class SourceExpon : public Source
00211 {
00212 private:
00213 bytestamp_t MeanGap;
00214 DOUBLE MeanBurst;
00215
00216 virtual inline int32u GetBurstSize(void) { return round<int32u>(_exponent_() * (MeanBurst - MIN_BURST) + MIN_BURST); }
00217 virtual inline bytestamp_t GetGapSize(void) { return _exponent_() * (MeanGap - Preamble ) + Preamble; }
00218
00219 public:
00220
00221 SourceExpon( int16u id,
00222 int16u prior,
00223 pct_size_t pct_sz,
00224 pct_size_t preamble,
00225 DOUBLE load,
00226 DOUBLE mean_burst ) : Source(id, prior, pct_sz, preamble )
00227 {
00228 MeanBurst = mean_burst;
00229 SetLoad( load );
00230 Reset();
00231 }
00232 virtual ~SourceExpon() {}
00234 virtual inline void SetLoad( DOUBLE load )
00235 {
00236 SetInRange<DOUBLE>( load, 0.0, 1.0 );
00237 MeanGap = SetGap( MeanBurst * ( PctSize / load - PctSpace ));
00238 }
00239 };
00240
00242 class SourceCBR : public Source
00243 {
00244 private:
00245 bytestamp_t Gap;
00246
00247 virtual inline int32u GetBurstSize(void) { return MIN_BURST; }
00248 virtual inline bytestamp_t GetGapSize(void) { return Gap; }
00249
00250 public:
00251
00252 SourceCBR( int16u id,
00253 int16u prior,
00254 pct_size_t pct_sz,
00255 pct_size_t preamble,
00256 DOUBLE load ) : Source(id, prior, pct_sz, preamble )
00257 {
00258 SetLoad( load );
00259 Reset();
00260 }
00261
00262 virtual ~SourceCBR() {}
00264 virtual inline void SetLoad( DOUBLE load )
00265 {
00266 SetInRange<DOUBLE>( load, 0.0, 1.0 );
00267 Gap = SetGap((1.0 / load - 1.0) * PctSize * MIN_BURST - Preamble);
00268 }
00269 };
00270
00271 #endif // _SOURCE_H_INCLUDED_