ATLAS Offline Software
PyStore.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 // PyStore.cxx
8 // Implementation file for class Py::Store
9 // Author: S.Binet<binet@cern.ch>
11 
12 // PerfMonEvent includes
13 #include "PerfMonEvent/PyStore.h"
14 
15 // STL includes
16 #include <iostream>
17 
18 namespace {
19  const std::size_t defaultBufferSize = 10;
20  const std::string s_uri = "://";
21 }
22 
23 namespace Py {
24 
25 std::string repr( PyObject* o )
26 {
27  // PyObject_Repr returns a new ref.
28  PyObject* py_repr = PyObject_Repr( o );
29  if ( !py_repr || !PyUnicode_Check(py_repr) ) {
30  Py_XDECREF( py_repr );
31  return "";
32  }
33 
34  std::string cpp_repr = PyUnicode_AsUTF8(py_repr);
35  Py_DECREF( py_repr );
36  return cpp_repr;
37 }
38 
40 // Public methods:
42 
43 // Constructors
45 
47  m_bufSize( defaultBufferSize ),
48  m_store ( PyDict_New() )
49 {}
50 
51 Store::Store( const std::size_t bufSize ) :
52  m_bufSize( bufSize ),
53  m_store ( PyDict_New() )
54 {}
55 
56 // Destructor
59 {
60  Py_DECREF( m_store );
61 }
62 
64 // const methods:
66 
67 std::string Store::repr()
68 {
69  return Py::repr( m_store );
70 }
71 
73 // Non-const methods:
75 
76 void Store::setBufferSize( std::size_t bufferSize )
77 {
78  if ( bufferSize <= m_bufSize ) {
80  return;
81  }
82 
84  // loop over buffers and extend their size
85 
86  return;
87 }
88 
90 {
91  PyObject *buffers = PyDict_Values( m_store );
92  if ( !buffers ) {
93  // error handling
94  Py_XDECREF( buffers );
95  return;
96  }
97 
98  for ( int i = 0, iMax = PyList_GET_SIZE( buffers ); i < iMax; ++i ) {
99  PyObject* buf = PyList_GET_ITEM( buffers, i );
100  Py_INCREF( buf );
101 
102  const int len = PyList_GET_SIZE( buf );
103 
104  // delete the whole slice
105  if ( PyList_SetSlice( buf, 0, len, (PyObject *) NULL ) != 0 ) {
106  // error handling
107 
108  Py_DECREF( buf );
109  continue;
110  }
111 
112  Py_DECREF( buf );
113  }
114 
115  Py_DECREF( buffers );
116  return;
117 }
118 
120 // Private methods:
122 
123 void Store::book_impl( const std::string& key,
124  const std::string& dataName,
125  char /*dataType*/ )
126 {
127  PyObject* buf = PyList_New( m_bufSize );
128  if ( !buf ) {
129  // error handling
130  std::cerr << "Store::book : Could not allocate a buffer for ["
131  << key << s_uri << dataName << "] !!\n";
132  Py_XDECREF(buf);
133  return;
134  }
135 
136  // resize to 0: >>> del buf[:]
137  if ( PyList_SetSlice( buf, 0, m_bufSize, (PyObject*)NULL ) != 0 ) {
138  // error handling
139  std::cerr << "Store::book : Could not reset allocated buffer ["
140  << key << s_uri << dataName << "] !!\n"
141  << " buf: " << Py::repr( buf ) << "\n";
142 
143  Py_DECREF(buf);
144  return;
145  }
146 
147  if ( PyDict_SetItemString( m_store,
148  const_cast<char*>((key+s_uri+dataName).c_str()),
149  buf ) != 0 ) {
150  // error handling
151  std::cerr << "Store::book : Could not create buffer at ["
152  << key << s_uri << dataName << "]\n"
153  << " buf: " << Py::repr( buf ) << "\n";
154  Py_DECREF(buf);
155  return;
156  }
157 }
158 
159 void Store::fill_impl( const std::string& key,
160  const std::string& dataName,
161  PyObject* data )
162 {
163  PyObject* buf =
164  PyDict_GetItemString( m_store,
165  const_cast<char*>((key+s_uri+dataName).c_str()) );
166  Py_XINCREF( buf );
167  if ( ! buf ) {
168  std::cerr << "Store::fill : Could not retrieve key ["
169  << key << s_uri << dataName << "] from store !!\n";
170 
171  // error handling
172  PyErr_Clear();
173  Py_DECREF ( data );
174  Py_XDECREF( buf );
175  return;
176  }
177 
178  if ( !PyList_Check( buf ) ) {
179  std::cerr << "Store::fill : buffer at ["
180  << key << s_uri << dataName << "] is NOT a python array !!\n"
181  << " buf: " << Py::repr( buf ) << "\n";
182 
183  // error handling
184  PyErr_Clear();
185  Py_DECREF( data );
186  Py_DECREF( buf );
187  return;
188  }
189 
190  if ( 0 != PyList_Append( buf, data ) ) {
191 
192  std::cerr << "Store::fill : could not fill buffer at ["
193  << key << s_uri << dataName << "] !!\n"
194  << " buf: " << Py::repr( buf ) << "\n"
195  << " data: " << Py::repr( data ) << "\n";
196 
197  // error handling
198  PyErr_Clear();
199  Py_DECREF( data );
200  Py_DECREF( buf );
201  return;
202  }
203 
204  Py_DECREF( data );
205  Py_DECREF( buf );
206  return;
207 }
208 
209 } //> end namespace Py
210 
211 // instantiates a few methods...
213 {
214  Py::Store s( 10 );
215  s.book<bool>( "f", "b" );
216  s.fill<bool>( "f", "b", true );
217 
218  s.book<double>( "f", "d" );
219  s.fill<double>( "f", "d", 1.2 );
220 
221  s.book<float>( "f", "f" );
222  s.fill<float>( "f", "f", 1.2 );
223 
224  s.book<int>( "f", "i" );
225  s.fill<int>( "f", "i", 1 );
226 
227  s.book<short int>( "f", "h" );
228  s.fill<short int>( "f", "h", 1 );
229 
230  s.book<unsigned int>( "f", "I" );
231  s.fill<unsigned int>( "f", "I", 10 );
232 
233  s.book<long int>( "f", "l" );
234  s.fill<long int>( "f", "l", 100 );
235 
236  s.book<unsigned long int>( "f", "k" );
237  s.fill<unsigned long int>( "f", "k", 1000 );
238 
239  {
240  std::vector<double> data(10);
241  s.book<std::vector<double> >( "f", "vd" );
242  s.fill<std::vector<double> >( "f", "vd", data );
243  }
244 
245  {
246  std::list<double> data(10);
247  s.book<std::list<double> >( "f", "ld" );
248  s.fill<std::list<double> >( "f", "ld", data );
249  }
250 
251  {
252  std::pair<double,float> data; data.first = 10.; data.second = 20.;
253  s.book<std::pair<double,float> >( "f", "p" );
254  s.fill<std::pair<double,float> >( "f", "p", data );
255  }
256 
257 
258 }
Py::Store::book_impl
void book_impl(const std::string &key, const std::string &dataName, char dataType='d')
register a variable with the store
Definition: PyStore.cxx:123
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
Py::Store::m_bufSize
std::size_t m_bufSize
the buffer size of all buckets (ie: the pre-reserved length of all PyArrays)
Definition: PyStore.h:141
Py::Store::repr
std::string repr()
python representation
Definition: PyStore.cxx:67
Py::Store::fill_impl
void fill_impl(const std::string &key, const std::string &dataName, PyObject *data)
fill some already registered node with data
Definition: PyStore.cxx:159
Py::Store
Definition: PyStore.h:37
Py::Store::m_store
PyObject * m_store
data store: a python dictionary
Definition: PyStore.h:144
Py::Store::bufferSize
std::size_t bufferSize() const
retrieve the current buffer size
Definition: PyStore.h:61
lumiFormat.i
int i
Definition: lumiFormat.py:92
Py::Store::Store
Store()
Constructor with parameters:
Definition: PyStore.cxx:46
Py::Store::clear_store
void clear_store()
clear buckets (but keeps registered/booked keys around)
Definition: PyStore.cxx:89
Py
Definition: PyDataStore.h:24
Py::Store::~Store
~Store()
Destructor:
Definition: PyStore.cxx:58
Py::repr
std::string repr(PyObject *o)
Definition: PyStore.cxx:25
instantiates
void instantiates()
Definition: PyStore.cxx:212
PyObject
_object PyObject
Definition: IPyComponent.h:26
Py::Store::setBufferSize
void setBufferSize(std::size_t bufferSize)
reset the buffer size.
Definition: PyStore.cxx:76
PyStore.h
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37