00001
00043
00044
00045
00046
00047
00048
00050
00051
00052
00053
00054 #ifndef _TRF_GEN_H_V003_INCLUDED_
00055 #define _TRF_GEN_H_V003_INCLUDED_
00056
00057
00058 #include "_types.h"
00059 #include "avltree.h"
00060
00061 template < class T > inline T SetInRange( T x, T y, T z )
00062 {
00063 if( x < y ) return y;
00064 if( x > z ) return z;
00065 return x;
00066 }
00067
00075 namespace GEN
00076 {
00077
00078 typedef int64u pause_size_t;
00079 typedef int64u burst_size_t;
00080
00081 typedef int64u bytestamp_t;
00082 typedef int16u pckt_size_t;
00083 typedef int16s source_id_t;
00084
00085 typedef float load_t;
00086 typedef float shape_t;
00087
00088 typedef DOUBLE rnd_real_t;
00089 typedef int32u rnd_int_t;
00090
00091 typedef pckt_size_t (*PF_PCKT_SIZE)( void );
00092
00093 const shape_t MIN_ALPHA = 1.001F;
00094 const shape_t MAX_ALPHA = 1.999F;
00095
00096 const load_t MIN_LOAD = 1.0E-10F;
00097 const load_t MAX_LOAD = 0.99999F;
00098
00099 const rnd_real_t SMALL_VAL = 1.0 / 0xFFFFFFFFUL;
00100
00108 struct Packet
00109 {
00110 source_id_t SourceId;
00111 pckt_size_t PcktSize;
00112 pause_size_t Interval;
00113
00114
00115
00116 };
00117
00118
00119
00127 class Stream: public AVL::AVLNode< bytestamp_t >
00128 {
00129
00130 #define BurstTime AVL::AVLNode<bytestamp_t>::NodeKey
00131
00132 friend class PacketGenerator;
00133 private:
00134
00135 burst_size_t BurstSize;
00136 int id;
00137
00138
00139 virtual inline burst_size_t NextBurstSize(void) {return 0;}
00140 virtual inline pause_size_t NextPauseSize(void) {return 0;}
00141
00142
00143 public:
00144
00145 Stream(): AVL::AVLNode< bytestamp_t >( 0 )
00146 {
00147 BurstSize = 0;
00148 }
00149
00150
00151 virtual ~Stream() {}
00152
00154
00155 virtual inline void SetLoad( load_t ) {}
00156
00158 inline void SetLoadRecursive( load_t load )
00159 {
00160 SetLoad( load );
00161 if( LChild ) ((Stream*)LChild)->SetLoadRecursive( load );
00162
00163 if( RChild ) ((Stream*)RChild)->SetLoadRecursive( load );
00164 }
00165
00167 inline void Reset(void)
00168 {
00169
00170
00171 BurstSize = NextBurstSize();
00172 BurstTime = NextPauseSize() + BurstSize;
00173
00174
00175
00176 bytestamp_t start_time = (bytestamp_t)uniform( 0, (rnd_real_t)BurstTime );
00177
00178
00179 if( start_time < BurstSize )
00180 {
00181 BurstSize -= (burst_size_t)start_time;
00182 BurstTime = 0;
00183 }
00184 else
00185 {
00186 BurstSize = NextBurstSize();
00187 BurstTime -= start_time;
00188 }
00189
00190 }
00191
00193 inline bytestamp_t GetArrival(void) const { return BurstTime; }
00194 inline burst_size_t GetBurstSize(void) const { return BurstSize; }
00195
00197
00198
00199
00201 inline void ExtractBurst(void)
00202 {
00203 BurstTime += BurstSize + NextPauseSize();
00204
00205
00206 BurstSize = NextBurstSize();
00207
00208
00209
00210 }
00212 };
00213
00214
00215
00223 class StreamPareto : public Stream
00224 {
00225 private:
00226
00227 float MinBurst;
00228 float MinPause;
00229 shape_t Shape;
00230
00231
00232 pause_size_t pause;
00233 burst_size_t burst;
00234
00235
00236 virtual inline burst_size_t NextBurstSize(void)
00237 {
00238
00239
00240
00241 burst=round<burst_size_t>(pareto_shifted(Shape,MinBurst,0));
00242 return burst;
00243 }
00244 virtual inline pause_size_t NextPauseSize(void)
00245 {
00246 pause=round<pause_size_t>(pareto_shifted(Shape,MinPause,0));
00247 return pause;
00248 }
00249
00250
00252
00253 public:
00254 StreamPareto( load_t ld, float mean_burst, shape_t shape ) : Stream()
00255 {
00256 Shape = SetInRange<shape_t>( shape, MIN_ALPHA, MAX_ALPHA );
00257 MinBurst = mean_burst * ( 1.0F - 1.0F / Shape );
00258 SetLoad( ld );
00259 Reset();
00260 }
00261
00262 virtual ~StreamPareto() {}
00263
00265 virtual inline void SetLoad( load_t load )
00266 {
00267 MinPause = MinBurst * ( 1.0F / SetInRange(load, MIN_LOAD, MAX_LOAD) - 1.0F );
00268 }
00269 };
00270
00271
00279 class StreamExpon : public Stream
00280 {
00281 private:
00282 float MeanPause;
00283 float MeanBurst;
00284
00285 burst_size_t burst;
00286 pause_size_t pause;
00287
00288 virtual inline burst_size_t NextBurstSize(void) {
00289 burst=round<burst_size_t>(exponential(MeanBurst));
00290 return burst;
00291 }
00292
00293 virtual inline pause_size_t NextPauseSize(void) {
00294 pause=round<pause_size_t>(exponential(MeanPause));
00295 return pause;
00296 }
00297
00299
00300 public:
00301
00302 StreamExpon( load_t ld, float mean_burst ) : Stream()
00303 {
00304 MeanBurst = mean_burst;
00305 SetLoad( ld );
00306 Reset();
00307 }
00309 virtual ~StreamExpon() {}
00311
00312 virtual inline void SetLoad( load_t load )
00313 {
00314 MeanPause = MeanBurst * ( 1.0F / SetInRange(load, MIN_LOAD, MAX_LOAD) - 1.0F );
00315 }
00317
00318 };
00319
00327 class StreamCBR : public Stream
00328 {
00329 private:
00330 burst_size_t BurstSize;
00331 pause_size_t PauseSize;
00332
00333 virtual inline burst_size_t NextBurstSize(void) { return BurstSize; }
00334 virtual inline pause_size_t NextPauseSize(void) { return PauseSize; }
00335
00337
00338 public:
00339
00340 StreamCBR( load_t ld, float mean_burst ) : Stream()
00341 {
00342 BurstSize = round<burst_size_t>( mean_burst );
00343 SetLoad( ld );
00344 Reset();
00345 }
00347 virtual ~StreamCBR() {}
00349
00350 virtual inline void SetLoad( load_t load )
00351 {
00352 PauseSize = round<pause_size_t>(BurstSize * (1.0F / SetInRange(load, MIN_LOAD, MAX_LOAD) - 1.0F));
00353 }
00355
00356 };
00357
00358
00359
00360
00368 typedef Stream* (*PF_STREAM_CTOR)( load_t, float ,int );
00369
00371 class PacketGenerator
00372 {
00374
00376 class StreamPool: public AVL::AVLTree< bytestamp_t >
00377 {
00378 public:
00379 inline Stream* GetRoot( void ) { return static_cast<Stream*>( pRoot ); }
00380 };
00381
00382
00383
00384 public:
00385
00386
00387 StreamPool Pool1, Pool2;
00388 StreamPool* BusyPool;
00389 StreamPool* IdlePool;
00390
00391 Packet NextPacket;
00392 bytestamp_t Elapsed;
00393 pckt_size_t MinIFG;
00394 burst_size_t Tokens;
00395
00396 PF_PCKT_SIZE pfPcktSize;
00397
00398
00399
00400
00401 public:
00403
00404
00406 PacketGenerator( source_id_t source_id, pckt_size_t inter_packet_gap ) {
00407 MinIFG = inter_packet_gap;
00408 BusyPool = &Pool1;
00409 IdlePool = &Pool2;
00410
00411 Tokens = 0;
00412 Elapsed = 0;
00413
00414 NextPacket.SourceId = source_id;
00415 NextPacket.PcktSize = 0;
00416 NextPacket.Interval = NextPacket.PcktSize + MinIFG;
00417
00418 }
00419
00421 PacketGenerator( source_id_t source_id,
00422 pckt_size_t inter_packet_gap,
00423 float mean_burst,
00424 PF_STREAM_CTOR pf_strm,
00425 PF_PCKT_SIZE pf_size,
00426 int16s pool_size,
00427 load_t load )
00428 {
00429 MinIFG = inter_packet_gap;
00430 BusyPool = &Pool1;
00431 IdlePool = &Pool2;
00432 pfPcktSize = pf_size;
00433 Tokens = 0;
00434 Elapsed = 0;
00435
00436
00437
00438
00439 NextPacket.SourceId = source_id;
00440 NextPacket.PcktSize = pfPcktSize();
00441 NextPacket.Interval = NextPacket.PcktSize + MinIFG;
00442
00443
00444 for( int16s s = 0; s < pool_size; s++ )
00445 {
00446 AddStream( pf_strm( load / pool_size, mean_burst,s ) );
00447
00448 }
00449
00450 }
00451
00453
00454
00455
00457 virtual ~PacketGenerator() { Clear(); }
00458
00460
00461
00462
00463
00465 void Reset( void )
00466 {
00467 for( Stream* pNode = RemoveStream(); pNode; pNode = RemoveStream() )
00468 {
00469 pNode->Reset();
00470 IdlePool->AddNode( pNode );
00471 }
00472
00473 SWAP<StreamPool*>( BusyPool, IdlePool );
00474 Elapsed = 0;
00475 }
00476
00478
00479 inline int32s GetStreams(void) const { return BusyPool->GetCount(); }
00480
00482
00483
00485 inline void AddStream( Stream* pSrc ) { BusyPool->AddNode( pSrc ); }
00486
00488
00489
00490
00492 inline void RemoveStream( Stream* pSrc )
00493 {
00494 BusyPool->RemoveNode( pSrc );
00495 }
00496
00497
00498 inline Stream* RemoveStream( void )
00499 {
00500 return (Stream*)BusyPool->RemoveHead();
00501 }
00502
00504
00505
00506
00508 inline Packet PeekNextPacket(void) const { return NextPacket; }
00509
00510
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00525 Packet GetNextPacket(void)
00526 {
00527 Stream* pStrm;
00528 Packet next_packet = NextPacket;
00529 pckt_size_t pckt_size = pfPcktSize();
00530 bytestamp_t pckt_time = Elapsed;
00531
00532
00533 pause_size_t interarrival_time;
00534
00535
00536
00537
00538
00539
00540
00541 while( Tokens < pckt_size && (pStrm = (Stream*)BusyPool->RemoveHead()) != NULL )
00542 {
00543 if( pStrm->GetArrival() > pckt_time + Tokens )
00544 pckt_time = pStrm->GetArrival() - Tokens;
00545
00546 Tokens += pStrm->GetBurstSize();
00547 pStrm->ExtractBurst();
00548 BusyPool->AddNode( pStrm );
00549 }
00550
00551 Tokens -= pckt_size;
00552 pckt_time += pckt_size + MinIFG;
00553
00554
00555 NextPacket.PcktSize = pckt_size;
00556 NextPacket.Interval =(pause_size_t)( pckt_time - Elapsed );
00557 interarrival_time= NextPacket.Interval - NextPacket.PcktSize;
00558
00559 Elapsed = pckt_time;
00560 return next_packet;
00561 }
00562
00563
00565
00566
00567
00569 void SetLoad( load_t load )
00570 {
00571 if( BusyPool->GetRoot() )
00572 BusyPool->GetRoot()->SetLoadRecursive( load / GetStreams() );
00573 }
00574
00576
00577
00578
00579
00580
00581
00582
00583
00585 inline void SetLoadReset( load_t load )
00586 {
00587 load /= GetStreams();
00588
00589 for( Stream* pNode = RemoveStream(); pNode; pNode = RemoveStream() )
00590 {
00591 pNode->SetLoad( load );
00592 pNode->Reset();
00593 IdlePool->AddNode( pNode );
00594
00595 }
00596
00597 SWAP<StreamPool*>( BusyPool, IdlePool );
00598 Elapsed = 0;
00599 }
00600
00602
00603
00604
00606 void Clear( void )
00607 {
00608 for( Stream* pNode = RemoveStream(); pNode; pNode = RemoveStream() )
00609 delete pNode;
00610
00611 Reset();
00612 }
00613
00614 };
00615
00616
00617
00618
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 };
00659
00660 #endif // _TRF_GEN_H_V003_INCLUDED_