Pol  Revision:cb584c9
proplist.cpp
Go to the documentation of this file.
1 
8 #include "proplist.h"
9 
10 #include <stddef.h>
11 
12 #include "../bscript/berror.h"
13 #include "../bscript/bobject.h"
14 #include "../bscript/executor.h"
15 #include "../bscript/impstr.h"
16 #include "../bscript/objmethods.h"
17 #include "../clib/cfgelem.h"
18 #include "../clib/logfacility.h"
19 #include "../clib/streamsaver.h"
20 #include "../clib/strutil.h"
21 #include "../plib/systemstate.h"
22 #include "baseobject.h"
23 #include "polcfg.h"
24 
25 #define pf_endl '\n'
26 namespace Pol
27 {
28 namespace Core
29 {
30 CPropProfiler::HitsCounter::HitsCounter() : hits( std::array<u64, 3>{{0, 0, 0}} ) {}
31 
33 {
34  return hits[idx];
35 }
36 
37 const u64& CPropProfiler::HitsCounter::operator[]( size_t idx ) const
38 {
39  return hits[idx];
40 }
41 
43 {
44  return sizeof( void* ) + sizeof( u64 ) * hits.size();
45 }
46 
49 {
50  switch ( oclass )
51  {
64  }
65 
69 }
70 
72 {
73  static CPropProfiler instance;
74  return instance;
75 }
76 
78 
83 {
84  PropLists::iterator el;
85  {
87  el = _proplists->find( proplist );
88  }
89 
90  if ( el == _proplists->end() )
91  {
95  return Type::UNKNOWN;
96  }
97 
98  return el->second;
99 }
100 
104 bool CPropProfiler::isIgnored( Type type ) const
105 {
106  if ( type == Type::DATAFILEELEMENT || type == Type::REGION )
107  return true;
108  return false;
109 }
110 
117 void CPropProfiler::cpropRead( const PropertyList* proplist, const std::string& name )
118 {
119  cpropAction( proplist, name, HitsCounter::READ );
120 }
127 void CPropProfiler::cpropWrite( const PropertyList* proplist, const std::string& name )
128 {
129  cpropAction( proplist, name, HitsCounter::WRITE );
130 }
138 void CPropProfiler::cpropErase( const PropertyList* proplist, const std::string& name )
139 {
140  cpropAction( proplist, name, HitsCounter::ERASE );
141 }
142 
150 {
152  _proplists->insert( std::make_pair( proplist, type ) );
153 }
154 
161 void CPropProfiler::registerProplist( const PropertyList* proplist, const PropertyList* copiedFrom )
162 {
163  registerProplist( proplist, getProplistType( copiedFrom ) );
164 }
165 
170 {
172  _proplists->erase( proplist );
173 }
174 
182 void CPropProfiler::cpropAction( const PropertyList* proplist, const std::string& name,
183  const size_t key )
184 {
185  Type type = getProplistType( proplist );
186  if ( isIgnored( type ) )
187  return;
188 
189  {
191  u64* cur = &( *_hits )[type][name][key];
192  if ( *cur < std::numeric_limits<u64>::max() )
193  ( *cur )++;
194  }
195 }
196 
201 {
204 
205  _proplists->clear();
206  _hits->clear();
207 }
208 
214 void CPropProfiler::dumpProfile( std::ostream& os ) const
215 {
216  // First generate the data
217 
218  // map<categoryname, map<typename, vector<lines> >>
219  std::map<std::string, std::map<std::string, std::vector<std::string>>> outData;
220 
221  {
223 
224  for ( auto tIter = _hits->begin(); tIter != _hits->end(); ++tIter )
225  {
226  Type t = tIter->first;
227 
228  std::string typeName;
229  switch ( t )
230  {
231  case Type::ACCOUNT:
232  typeName = "Account";
233  break;
234  case Type::GUILD:
235  typeName = "Guild";
236  break;
237  case Type::GLOBAL:
238  typeName = "Global";
239  break;
240  case Type::ITEM:
241  typeName = "Item";
242  break;
243  case Type::MOBILE:
244  typeName = "Mobile";
245  break;
246  case Type::MULTI:
247  typeName = "Multi";
248  break;
249  case Type::PARTY:
250  typeName = "Party";
251  break;
252  case Type::UNKNOWN:
253  typeName = "UNKNOWN";
254  break;
255  default:
256  typeName = "ERROR " + std::to_string( static_cast<unsigned int>( t ) );
257  break;
258  }
259 
260  for ( auto pIter = tIter->second.begin(); pIter != tIter->second.end(); ++pIter )
261  {
262  std::ostringstream line;
263  line << pIter->first << " ";
264  line << pIter->second[HitsCounter::READ] << "/";
265  line << pIter->second[HitsCounter::WRITE] << "/";
266  line << pIter->second[HitsCounter::ERASE] << std::endl;
267 
268  if ( !pIter->second[HitsCounter::READ] )
269  outData["WRITTEN BUT NEVER READ"][typeName].push_back( line.str() );
270  else if ( !pIter->second[HitsCounter::WRITE] )
271  outData["READ BUT NEVER WRITTEN"][typeName].push_back( line.str() );
272  else
273  outData["ALL THE REST"][typeName].push_back( line.str() );
274  }
275  }
276  }
277 
278  // Then output it
279  for ( auto it1 = outData.rbegin(); it1 != outData.rend(); ++it1 )
280  {
281  // 1st level header
282  os << std::string( 15, '-' ) << " " << it1->first << " " << std::string( 15, '-' ) << std::endl;
283 
284  for ( auto it2 = it1->second.begin(); it2 != it1->second.end(); ++it2 )
285  {
286  // 2nd level header
287  os << it2->first << " CProps summary (read/write/erase):" << std::endl;
288 
289  std::sort( it2->second.begin(), it2->second.end() );
290  for ( auto it3 = it2->second.begin(); it3 != it2->second.end(); ++it3 )
291  {
292  os << "- " << *it3;
293  }
294  }
295 
296  os << std::endl;
297  }
298 }
299 
304 {
306  size_t ret = sizeof( Clib::SpinLock ) + sizeof( _proplistsLock ) + sizeof( _hits ) +
307  sizeof( _proplists ) + sizeof( void* ) * 2;
308 
310  {
312  ret += ( sizeof( PropertyList* ) + sizeof( Type ) ) * _proplists->size();
313  }
314 
316  {
318  for ( auto itr1 = _hits->begin(); itr1 != _hits->end(); ++itr1 )
319  {
320  ret += sizeof( Type ) + sizeof( HitsEntries );
321  for ( auto itr2 = itr1->second.begin(); itr2 != itr1->second.end(); ++itr2 )
322  {
323  ret += itr2->first.size() + itr2->second.sizeEstimate();
324  }
325  }
326  }
327 
328  return ret;
329 }
330 
336 {
337  if ( Plib::systemstate.config.profile_cprops )
339 }
340 
346 {
347  if ( force || Plib::systemstate.config.profile_cprops )
349 }
350 
355 {
356  copyprops( props );
357 
358  if ( Plib::systemstate.config.profile_cprops )
359  CPropProfiler::instance().registerProplist( this, &props );
360 }
361 
363 {
364  size_t size = sizeof( PropertyList );
365  size += properties.size() *
367  sizeof( boost_utils::cprop_value_flystring ) + ( sizeof( void* ) * 3 + 1 ) / 2 );
368  return size;
369 }
370 
371 bool PropertyList::getprop( const std::string& propname, std::string& propval ) const
372 {
373  if ( Plib::systemstate.config.profile_cprops )
374  CPropProfiler::instance().cpropRead( this, propname );
375 
376  Properties::const_iterator itr = properties.find( boost_utils::cprop_name_flystring( propname ) );
377  if ( itr == properties.end() )
378  {
379  return false;
380  }
381  else
382  {
383  propval = ( *itr ).second;
384  return true;
385  }
386 }
387 void PropertyList::setprop( const std::string& propname, const std::string& propvalue )
388 {
389  if ( Plib::systemstate.config.profile_cprops )
390  CPropProfiler::instance().cpropWrite( this, propname );
391 
392  properties[boost_utils::cprop_name_flystring( propname )] = propvalue;
393 }
394 
395 void PropertyList::eraseprop( const std::string& propname )
396 {
397  if ( Plib::systemstate.config.profile_cprops )
398  CPropProfiler::instance().cpropErase( this, propname );
399 
400  properties.erase( boost_utils::cprop_name_flystring( propname ) );
401 }
402 
404 {
405  // dave 4/25/3 map insert won't overwrite with new values, so remove those first and then
406  // reinsert.
407  if ( !properties.empty() )
408  {
409  for ( const auto& prop : from.properties )
410  properties.erase( prop.first );
411  }
412 
413  properties.insert( from.properties.begin(), from.properties.end() );
414 }
415 
417 {
418  properties.clear();
419 }
420 
421 void PropertyList::getpropnames( std::vector<std::string>& propnames ) const
422 {
423  for ( const auto& prop : properties )
424  {
425  propnames.push_back( prop.first );
426  }
427 }
428 
430 {
431  for ( const auto& prop : properties )
432  {
433  const std::string& first = prop.first;
434  if ( first[0] != '#' )
435  {
436  sw() << "\tCProp\t" << first << " " << prop.second.get() << pf_endl;
437  }
438  }
439 }
441 {
442  for ( const auto& prop : properties )
443  {
444  const std::string& first = prop.first;
445  if ( first[0] != '#' )
446  {
447  elem.add_prop( "CProp", ( first + "\t" + prop.second.get() ) );
448  }
449  }
450 }
451 
453 {
454  for ( const auto& prop : properties )
455  {
456  const std::string& first = prop.first;
457  if ( first[0] != '#' )
458  {
459  sw() << "\t" << first << " " << prop.second.get() << pf_endl;
460  }
461  }
462 }
463 
465 {
466  std::string tempstr;
467  while ( elem.remove_prop( "StrProp", &tempstr ) )
468  {
469  std::string propname;
470  std::string propvalue;
471 
472  Clib::splitnamevalue( tempstr, propname, propvalue );
473 
474  setprop( propname, "s" + propvalue );
475  }
476  while ( elem.remove_prop( "CProp", &tempstr ) )
477  {
478  std::string propname;
479  std::string propvalue;
480 
481  Clib::splitnamevalue( tempstr, propname, propvalue );
482 
483  setprop( propname, propvalue );
484  }
485 }
486 
488 {
489  std::string propname, propvalue;
490  while ( elem.remove_first_prop( &propname, &propvalue ) )
491  {
492  setprop( propname, propvalue );
493  }
494 }
495 
496 bool PropertyList::operator==( const PropertyList& plist ) const
497 {
498  return ( this->properties == plist.properties );
499 }
500 
502  const std::set<std::string>& CPropNames ) // dave added 1/26/3
503 {
504  for ( const auto& name : CPropNames )
505  {
506  eraseprop( name );
507  }
508 
509  return *this;
510 }
511 
512 void PropertyList::operator-=( const std::set<std::string>& CPropNames ) // dave added 1/26/3
513 {
514  for ( const auto& name : CPropNames )
515  {
516  eraseprop( name );
517  }
518 }
519 
521  Bscript::Executor& ex, bool& changed )
522 {
523  using namespace Bscript;
524  switch ( id )
525  {
526  case MTH_GETPROP:
527  {
528  if ( !ex.hasParams( 1 ) )
529  return new BError( "Not enough parameters" );
530  const String* propname_str;
531  if ( !ex.getStringParam( 0, propname_str ) )
532  return new BError( "Invalid parameter type" );
533  std::string val;
534  if ( !proplist.getprop( propname_str->value(), val ) )
535  return new BError( "Property not found" );
536 
537  return Bscript::BObjectImp::unpack( val.c_str() );
538  }
539 
540  case MTH_SETPROP:
541  {
542  if ( !ex.hasParams( 2 ) )
543  return new BError( "Not enough parameters" );
544  const String* propname_str;
545  if ( !ex.getStringParam( 0, propname_str ) )
546  return new BError( "Invalid parameter type" );
547 
548  Bscript::BObjectImp* propval = ex.getParamImp( 1 );
549  if ( propval->isa( Bscript::BObjectImp::OTError ) )
550  {
551  POLLOG.Format( "wtf, setprop w/ an error '{}' PC:{}\n" ) << ex.scriptname().c_str() << ex.PC;
552  }
553  std::string propname = propname_str->value();
554  proplist.setprop( propname, propval->pack() );
555  if ( propname[0] != '#' )
556  changed = true;
557  return new BLong( 1 );
558  }
559 
560  case MTH_ERASEPROP:
561  {
562  if ( !ex.hasParams( 1 ) )
563  return new BError( "Not enough parameters" );
564  const String* propname_str;
565  if ( !ex.getStringParam( 0, propname_str ) )
566  return new BError( "Invalid parameter type" );
567  std::string propname = propname_str->value();
568  proplist.eraseprop( propname );
569  if ( propname[0] != '#' )
570  changed = true;
571  return new BLong( 1 );
572  }
573 
574  case MTH_PROPNAMES:
575  {
576  std::vector<std::string> propnames;
577  proplist.getpropnames( propnames );
578  std::unique_ptr<ObjArray> arr( new ObjArray );
579  for ( const auto& name : propnames )
580  {
581  arr->addElement( new String( name ) );
582  }
583  return arr.release();
584  }
585 
586  default:
587  return nullptr;
588  }
589 }
590 
591 Bscript::BObjectImp* CallPropertyListMethod( PropertyList& proplist, const char* methodname,
592  Bscript::Executor& ex, bool& changed )
593 {
594  Bscript::ObjMethod* objmethod = Bscript::getKnownObjMethod( methodname );
595  if ( objmethod != nullptr )
596  return CallPropertyListMethod_id( proplist, objmethod->id, ex, changed );
597  else
598  return nullptr;
599 }
600 }
601 }
void printProperties(Clib::StreamWriter &sw) const
Definition: proplist.cpp:429
bool operator==(const PropertyList &) const
Definition: proplist.cpp:496
bool remove_first_prop(std::string *propname, std::string *value)
Definition: cfgfile.cpp:100
const std::string & value() const
Definition: impstr.h:67
void splitnamevalue(const std::string &istr, std::string &propname, std::string &propvalue)
Definition: strutil.cpp:107
std::unique_ptr< Hits > _hits
Definition: proplist.h:118
SystemState systemstate
Definition: systemstate.cpp:12
bool isa(BObjectType type) const
Definition: bobject.h:353
std::array< u64, 3 > hits
0=read, 1=write, 2=erase
Definition: proplist.h:105
static CPropProfiler & instance()
Definition: proplist.cpp:71
Clib::SpinLock _hitsLock
Definition: proplist.h:120
STL namespace.
size_t estimatedSize() const
Definition: proplist.cpp:362
std::unique_ptr< PropLists > _proplists
Definition: proplist.h:117
ObjMethod * getKnownObjMethod(const char *token)
Definition: parser.cpp:666
void eraseprop(const std::string &propname)
Definition: proplist.cpp:395
virtual std::string pack() const
Definition: object.cpp:201
bool isIgnored(Type type) const
Definition: proplist.cpp:104
void readRemainingPropertiesAsStrings(Clib::ConfigElem &elem)
Definition: proplist.cpp:487
Bscript::BObjectImp * CallPropertyListMethod_id(PropertyList &proplist, const int id, Bscript::Executor &ex, bool &changed)
Definition: proplist.cpp:520
unsigned long long u64
Definition: rawtypes.h:38
boost::flyweight< std::string, boost::flyweights::tag< cprop_name_tag >, FLYWEIGHT_HASH_FACTORY > cprop_name_flystring
Definition: boostutils.h:125
void add_prop(std::string propname, std::string propval)
Definition: cfgfile.cpp:490
void setprop(const std::string &propname, const std::string &propvalue)
Definition: proplist.cpp:387
void unregisterProplist(const PropertyList *proplist)
Definition: proplist.cpp:169
Properties properties
Definition: proplist.h:161
std::map< const PropertyList *, const Type > PropLists
Definition: proplist.h:107
void copyprops(const PropertyList &proplist)
Definition: proplist.cpp:403
void registerProplist(const PropertyList *proplist, const Type type)
Definition: proplist.cpp:149
void printPropertiesAsStrings(Clib::StreamWriter &sw) const
Definition: proplist.cpp:452
#define POLLOG
Definition: logfacility.h:219
void readProperties(Clib::ConfigElem &elem)
Definition: proplist.cpp:464
static BObjectImp * unpack(const char *pstr)
Definition: object.cpp:120
unknown type, do not use (internally used when profiler is enabled after startup) ...
size_t estimateSize() const
Definition: proplist.cpp:303
void getpropnames(std::vector< std::string > &propnames) const
Definition: proplist.cpp:421
std::map< const std::string, HitsCounter > HitsEntries
Definition: proplist.h:108
std::map< const Type, HitsEntries > Hits
Definition: proplist.h:109
bool remove_prop(const char *propname, std::string *value)
Definition: cfgfile.cpp:128
Clib::SpinLock _proplistsLock
Definition: proplist.h:119
const std::string & scriptname() const
Definition: executor.h:413
const String * getStringParam(unsigned param)
Definition: executor.cpp:347
void cpropErase(const PropertyList *proplist, const std::string &name)
Definition: proplist.cpp:138
bool getprop(const std::string &propname, std::string &propvalue) const
Definition: proplist.cpp:371
std::string name
Definition: osmod.cpp:943
bool hasParams(unsigned howmany) const
Definition: executor.h:144
void operator-=(const std::set< std::string > &)
Definition: proplist.cpp:512
Bscript::BObjectImp * CallPropertyListMethod(PropertyList &proplist, const char *methodname, Bscript::Executor &ex, bool &changed)
Definition: proplist.cpp:591
PropertyList & operator-(const std::set< std::string > &)
Definition: proplist.cpp:501
boost::flyweight< std::string, boost::flyweights::tag< cprop_value_tag >, FLYWEIGHT_HASH_FACTORY > cprop_value_flystring
Definition: boostutils.h:131
void cpropAction(const PropertyList *proplist, const std::string &name, const size_t key)
Definition: proplist.cpp:182
void cpropWrite(const PropertyList *proplist, const std::string &name)
Definition: proplist.cpp:127
static Type class_to_type(UOBJ_CLASS oclass)
Definition: proplist.cpp:48
#define pf_endl
Definition: proplist.cpp:25
std::lock_guard< SpinLock > SpinLockGuard
Definition: spinlock.h:33
void dumpProfile(std::ostream &os) const
Definition: proplist.cpp:214
void cpropRead(const PropertyList *proplist, const std::string &name)
Definition: proplist.cpp:117
Definition: berror.cpp:12
Type getProplistType(const PropertyList *proplist) const
Definition: proplist.cpp:82
BObjectImp * getParamImp(unsigned param)
Definition: executor.cpp:266