1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "processing_spreader.h"
21 #include "frontend_service.h"
27 CProcessingSpreader::CProcessingSpreader() :
28 ExecutionPeriod(1), _ClientMapIndex(0), _Invalidated(true)
29 #ifdef TEST_WORSE_EXECUTION_PERIOD
39 void CProcessingSpreader::init()
41 _ClientMapIterator
= CFrontEndService::instance()->receiveSub()->clientMap().end();
46 * Get the range (beginning iterator, index and outer bound) for the current processing
48 void CProcessingSpreader::getProcessingBounds( THostMap::iterator
& firstit
, sint
& firstindex
, sint
& outerboundindex
)
50 THostMap
& clientmap
= CFrontEndService::instance()->receiveSub()->clientMap();
51 sint nbClients
= (sint
)clientmap
.size();
53 // Test if the index has reached the end of the client map
54 if ( _ClientMapIndex
>= nbClients
)
56 // The range begins at the beginning of the client map
57 firstit
= clientmap
.begin();
62 // Return the current iterator (if it is valid)
67 // Rescan the client map to get the new iterator
68 // It is necessary when the client referenced by _ClientMapIndex left the FE.
69 THostMap::iterator it
= clientmap
.begin();
70 for ( sint i
=0; i
!=_ClientMapIndex
; ++i
, ++it
);
72 firstindex
= _ClientMapIndex
;
73 //nlinfo( "%p: Scanning client map to index %d, iterator %p", this, firstindex, firstit );
77 // _ClientMapIterator is valid if and only if endProcessing() was called
78 // since the previous getProcessingBounds()
79 firstit
= _ClientMapIterator
;
80 firstindex
= _ClientMapIndex
;
81 //nlinfo( "%p: Giving back index %d, iterator %p", this, firstindex, firstit );
85 sint maxNbClientsProcessedPerTick
= MaxNbClients
/ ExecutionPeriod
;
86 outerboundindex
= firstindex
+ std::min( maxNbClientsProcessedPerTick
, nbClients
- firstindex
);
87 _ClientMapIndex
= outerboundindex
;
92 * Method to call after a new client is added into the clientmap
94 void CProcessingSpreader::notifyClientAddition( THostMap::iterator endBeforeAddition
)
96 THostMap
& clientmap
= CFrontEndService::instance()->receiveSub()->clientMap();
97 //nlinfo( "%p: Addition, iterator=%p", this, _ClientMapIterator );
99 // NEW: Always (because an addition may be an insertion => mismatch between index and iterator)
100 _ClientMapIterator
= clientmap
.begin();
103 // If _ClientMapIterator was pointed on the end, reset it
104 /*if ( _ClientMapIterator == endBeforeAddition )
106 // Necessary for getProcessingBounds() to work when there is no invalidation
107 _ClientMapIterator = clientmap.begin();
108 //nlinfo( "%p: Resetting to begin", this );
114 void CProcessingSpreader::notifyClientRemoval( THostMap::iterator icm
)
116 //nlinfo( "%p: Removal", this );
117 if ( (!_Invalidated
) && (_ClientMapIterator
== icm
) ) // without the test of !_Invalidated, stldebug will cry in operator==() if calling notifyClientRemoval() twice (the second time, _ClientMapIterator points to an erased element)
120 //nlinfo( "%p: Iterator=%p leaving => invalidate!" );