summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelie <elie>2011-01-23 09:04:39 +0000
committerelie <elie>2011-01-23 09:04:39 +0000
commit16301f2c4d7116cc0acaea1bb965713a2f022159 (patch)
tree7960f59c7f3d11f555079f1eab684a80569319f5
parent97d80236180d9524b4a286b9521e36bc76ed059b (diff)
downloadpysnmp-16301f2c4d7116cc0acaea1bb965713a2f022159.tar.gz
cache MIB columnar objects instance ID <-> symbolic representation mapping
for performance reasons
-rw-r--r--pysnmp/cache.py37
-rw-r--r--pysnmp/smi/mibs/SNMPv2-SMI.py13
2 files changed, 48 insertions, 2 deletions
diff --git a/pysnmp/cache.py b/pysnmp/cache.py
new file mode 100644
index 0000000..4023c46
--- /dev/null
+++ b/pysnmp/cache.py
@@ -0,0 +1,37 @@
+# Limited-size dictionary class to use for caches
+
+class Cache:
+ def __init__(self, maxSize=256):
+ self.__maxSize = maxSize
+ self.__size = 0
+ self.__chopSize = maxSize/10
+ self.__chopSize = self.__chopSize and self.__chopSize or 1
+ self.__cache = {}
+ self.__usage = {}
+
+ def __contains__(self, k): return k in self.__cache
+
+ def __getitem__(self, k):
+ self.__usage[k] = self.__usage[k] + 1
+ return self.__cache[k]
+
+ def __len__(self): return self.__size
+
+ def __setitem__(self, k, v):
+ if self.__size >= self.__maxSize:
+ keys = self.__usage.keys()
+ keys.sort(lambda x,y,d=self.__usage: cmp(d[x],d[y]))
+ print keys[:self.__chopSize]
+ for _k in keys[:self.__chopSize]:
+ del self.__cache[_k]
+ del self.__usage[_k]
+ self.__size = self.__size - self.__chopSize
+ if k not in self.__cache:
+ self.__size = self.__size + 1
+ self.__usage[k] = 0L
+ self.__cache[k] = v
+
+ def __delitem__(self, k):
+ del self.__cache[k]
+ del self.__usage[k]
+ self.__size = self.__size - 1
diff --git a/pysnmp/smi/mibs/SNMPv2-SMI.py b/pysnmp/smi/mibs/SNMPv2-SMI.py
index a47ca93..9af9477 100644
--- a/pysnmp/smi/mibs/SNMPv2-SMI.py
+++ b/pysnmp/smi/mibs/SNMPv2-SMI.py
@@ -4,7 +4,7 @@ from pysnmp.smi import exval, error
from pysnmp.proto import rfc1902
from pyasn1.type import constraint
from pyasn1.error import ValueConstraintError, PyAsn1Error
-from pysnmp import debug
+from pysnmp import cache, debug
( Integer, ObjectIdentifier, Null ) = mibBuilder.importSymbols("ASN1", "Integer", "ObjectIdentifier", "Null")
@@ -756,6 +756,8 @@ class MibTableRow(MibTree):
"""
def __init__(self, name):
MibTree.__init__(self, name)
+ self.__idToIdxCache = cache.Cache()
+ self.__idxToIdCache = cache.Cache()
self.indexNames = ()
self.augmentingRows = {}
@@ -962,6 +964,8 @@ class MibTableRow(MibTree):
def getIndicesFromInstId(self, instId):
"""Return index values for instance identification"""
+ if instId in self.__idToIdxCache:
+ return self.__idToIdxCache[instId]
indices = []
for impliedFlag, modName, symName in self.indexNames:
mibObj, = mibBuilder.importSymbols(modName, symName)
@@ -972,10 +976,14 @@ class MibTableRow(MibTree):
'Excessive instance identifier sub-OIDs left at %s: %s' %
(self, instId)
)
- return tuple(indices)
+ indices = tuple(indices)
+ self.__idToIdxCache[instId] = indices
+ return indices
def getInstIdFromIndices(self, *indices):
"""Return column instance identification from indices"""
+ if indices in self.__idxToIdCache:
+ return self.__idxToIdCache[indices]
idx = 0; idxLen = len(indices); instId = ()
for impliedFlag, modName, symName in self.indexNames:
mibObj, = mibBuilder.importSymbols(modName, symName)
@@ -986,6 +994,7 @@ class MibTableRow(MibTree):
else:
break
idx = idx + 1
+ self.__idxToIdCache[indices] = instId
return instId
# Table access by index