forked from panda3d/panda3d
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathObjectPool.py
More file actions
executable file
·134 lines (119 loc) · 4.69 KB
/
ObjectPool.py
File metadata and controls
executable file
·134 lines (119 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
"""Contains the ObjectPool utility class."""
__all__ = ['Diff', 'ObjectPool']
from direct.directnotify.DirectNotifyGlobal import directNotify
from direct.showbase.PythonUtil import invertDictLossless, makeList, safeRepr
from direct.showbase.PythonUtil import getNumberedTypedString, getNumberedTypedSortedString
import gc
class Diff:
def __init__(self, lost, gained):
self.lost=lost
self.gained=gained
def printOut(self, full=False):
print('lost %s objects, gained %s objects' % (len(self.lost), len(self.gained)))
print('\n\nself.lost\n')
print(self.lost.typeFreqStr())
print('\n\nself.gained\n')
print(self.gained.typeFreqStr())
if full:
self.gained.printObjsByType()
print('\n\nGAINED-OBJECT REFERRERS\n')
self.gained.printReferrers(1)
class ObjectPool:
"""manipulate a pool of Python objects"""
notify = directNotify.newCategory('ObjectPool')
def __init__(self, objects):
self._objs = list(objects)
self._type2objs = {}
self._count2types = {}
self._len2obj = {}
type2count = {}
for obj in self._objs:
typ = itype(obj)
type2count.setdefault(typ, 0)
type2count[typ] += 1
self._type2objs.setdefault(typ, [])
self._type2objs[typ].append(obj)
try:
self._len2obj[len(obj)] = obj
except:
pass
self._count2types = invertDictLossless(type2count)
def _getInternalObjs(self):
return (self._objs, self._type2objs, self._count2types)
def destroy(self):
del self._objs
del self._type2objs
del self._count2types
def getTypes(self):
return list(self._type2objs.keys())
def getObjsOfType(self, type):
return self._type2objs.get(type, [])
def printObjsOfType(self, type):
for obj in self._type2objs.get(type, []):
print(repr(obj))
def diff(self, other):
"""print difference between this pool and 'other' pool"""
thisId2obj = {}
otherId2obj = {}
for obj in self._objs:
thisId2obj[id(obj)] = obj
for obj in other._objs:
otherId2obj[id(obj)] = obj
thisIds = set(thisId2obj.keys())
otherIds = set(otherId2obj.keys())
lostIds = thisIds.difference(otherIds)
gainedIds = otherIds.difference(thisIds)
del thisIds
del otherIds
lostObjs = []
for i in lostIds:
lostObjs.append(thisId2obj[i])
gainedObjs = []
for i in gainedIds:
gainedObjs.append(otherId2obj[i])
return Diff(self.__class__(lostObjs), self.__class__(gainedObjs))
def typeFreqStr(self):
s = 'Object Pool: Type Frequencies'
s += '\n============================='
counts = list(set(self._count2types.keys()))
counts.sort()
counts.reverse()
for count in counts:
types = makeList(self._count2types[count])
for typ in types:
s += '\n%s\t%s' % (count, typ)
return s
def printObjsByType(self):
print('Object Pool: Objects By Type')
print('\n============================')
counts = list(set(self._count2types.keys()))
counts.sort()
# print types with the smallest number of instances first, in case
# there's a large group that waits a long time before printing
#counts.reverse()
for count in counts:
types = makeList(self._count2types[count])
for typ in types:
print('TYPE: %s, %s objects' % (repr(typ), len(self._type2objs[typ])))
print(getNumberedTypedSortedString(self._type2objs[typ]))
def printReferrers(self, numEach=3):
"""referrers of the first few of each type of object"""
counts = list(set(self._count2types.keys()))
counts.sort()
counts.reverse()
for count in counts:
types = makeList(self._count2types[count])
for typ in types:
print('\n\nTYPE: %s' % repr(typ))
for i in range(min(numEach, len(self._type2objs[typ]))):
obj = self._type2objs[typ][i]
print('\nOBJ: %s\n' % safeRepr(obj))
referrers = gc.get_referrers(obj)
print('%s REFERRERS:\n' % len(referrers))
if len(referrers):
print(getNumberedTypedString(referrers, maxLen=80,
numPrefix='REF'))
else:
print('<No Referrers>')
def __len__(self):
return len(self._objs)