[lisp-snmp] ipAdEntAddr versus the simple-oid-cache
Brought to you by:
binghe
From: John F. <jf...@ms...> - 2009-06-09 08:48:09
|
Dear Chun Tian, We have to walk IF-MIB::ipAdEntAddr from many routers. The results of this are a list of IP addresses the router has. Unfortunately, each OID in the result encodes the IP address. For example, IP-MIB::ipAdEntAddr.127.0.0.1 = IpAddress: 127.0.0.1 We were fetching from many routers and storing these OIDs, so the *simple-oid-cache* was getting full. The :test 'equal on the OIDs with similar prefixes was very slow. Without the cache our benchmark completes in about 5 seconds, with the cache it does not complete after a few minutes. We were mucking about with some code for replacing the simple-oid-cache with one that is limited in size. However, in our case, there isn't any benefit in having the cache at all, as the OIDs are always different, so we stopped our experiments. In case you are interested, the experiments are below (note that the array version incorrectly does not check if the element in the array actually has a matching oid-number-list). What was the reason for introducing the simple-oid-cache in the first place? Maybe we can develop a compromise version that suits both use cases? PS. I am sorry, I made a mistake about the weakness for the hash table -- it can be downgraded to :weakness :value, I think. Index: oid-reader.lisp =================================================================== --- oid-reader.lisp (revision 769) +++ oid-reader.lisp (working copy) @@ -81,10 +81,42 @@ (defmethod oid ((oid-vector vector)) (oid (coerce oid-vector 'list))) +#+ (and asn.1-features:oid-cache nil) +(progn + (defvar *simple-oid-cache* + (trivial-garbage:make-weak-hash-table :test 'equal + :weakness :value)) + + (defun (setf simple-oid-cache) (oid oid-number-list) + (setf (gethash oid-number-list *simple-oid-cache*) oid)) + + (defun simple-oid-cache (oid-number-list) + (gethash oid-number-list *simple-oid-cache*)) +) + #+asn.1-features:oid-cache -(defvar *simple-oid-cache* (make-hash-table :test 'equal - #+lispworks :weak-kind #+lispworks :value)) +(progn + (defvar *simple-oid-cache* + (make-array 10)) + + (defun simple-oid-cache-hash (list) + (declare (optimize speed)) + (let ((sum 0)) + (declare (type fixnum sum)) + (loop for i of-type unsigned-byte in list + do (setf sum (mod (* 17 (+ (* 13 sum) i)) (1+ most-positive-fixnum)))) + (mod sum (length *simple-oid-cache*)))) + (defmacro simple-oid-cache-aref (oid-number-list) + `(aref *simple-oid-cache* (simple-oid-cache-hash ,oid-number-list))) + + (defun (setf simple-oid-cache) (oid oid-number-list) + (setf (simple-oid-cache-aref oid-number-list) oid)) + + (defun simple-oid-cache (oid-number-list) + (simple-oid-cache-aref oid-number-list))) + + (defun oid-helper (tokens base) (declare (type list tokens) (type object-id base)) @@ -99,7 +131,7 @@ (oid-helper (cdr tokens) b) (let ((o (make-instance 'simple-oid :value tokens :parent base))) #+asn.1-features:oid-cache - (setf (gethash (oid-number-list o) *simple-oid-cache*) o) + (setf (simple-oid-cache (oid-number-list o)) o) o)))) (symbol ; walk through children of base to find a child with the name (with-hash-table-iterator (get-child (oid-children base)) @@ -121,7 +153,7 @@ ;; optimize: plain number list directly to simple-oid when possible (if #+asn.1-features:oid-cache (every #'numberp (cdr oid-tokens)) #-asn.1-features:oid-cache nil - (let ((o (gethash oid-tokens *simple-oid-cache*))) + (let ((o (simple-oid-cache oid-tokens))) (or o (prog1 (oid-helper oid-tokens |zero|) #+ignore |