diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-03-31 19:17:43 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-04-01 17:28:53 +0900 |
commit | e1e89ce57f95110d415d1fa368a73ed5eb213a63 (patch) | |
tree | f2215caba3b2f33b4dd689579964ea6c31ea9991 /ryu/services/protocols/bgp/utils/internable.py | |
parent | d6bbd8349760e1fb93e74353f751eee1b025912b (diff) |
add BGP daemon feature
Currently, the BGP code can work as an daemon (IOW, not RyuApp).
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'ryu/services/protocols/bgp/utils/internable.py')
-rw-r--r-- | ryu/services/protocols/bgp/utils/internable.py | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/ryu/services/protocols/bgp/utils/internable.py b/ryu/services/protocols/bgp/utils/internable.py new file mode 100644 index 00000000..ae39798c --- /dev/null +++ b/ryu/services/protocols/bgp/utils/internable.py @@ -0,0 +1,102 @@ +# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import weakref + +dict_name = intern('_internable_dict') + + +# +# Internable +# +class Internable(object): + """Class that allows instances to be 'interned'. That is, given an + instance of this class, one can obtain a canonical (interned) + copy. + + This saves memory when there are likely to be many identical + instances of the class -- users hold references to a single + interned object instead of references to different objects that + are identical. + + The interned version of a given instance is created on demand if + necessary, and automatically cleaned up when nobody holds a + reference to it. + + Instances of sub-classes must be usable as dictionary keys for + Internable to work. + """ + + class Stats(object): + + def __init__(self): + self.d = {} + + def incr(self, name): + self.d[name] = self.d.get(name, 0) + 1 + + def __repr__(self): + return repr(self.d) + + def __str__(self): + return str(self.d) + + @classmethod + def _internable_init(kls): + # Objects to be interned are held as keys in a dictionary that + # only holds weak references to keys. As a result, when the + # last reference to an interned object goes away, the object + # will be removed from the dictionary. + kls._internable_dict = weakref.WeakKeyDictionary() + kls._internable_stats = Internable.Stats() + + @classmethod + def intern_stats(kls): + return kls._internable_stats + + def intern(self): + """Returns either itself or a canonical copy of itself.""" + + # If this is an interned object, return it + if hasattr(self, '_interned'): + return self._internable_stats.incr('self') + + # + # Got to find or create an interned object identical to this + # one. Auto-initialize the class if need be. + # + kls = self.__class__ + + if not hasattr(kls, dict_name): + kls._internable_init() + + obj = kls._internable_dict.get(self) + if (obj): + # Found an interned copy. + kls._internable_stats.incr('found') + return obj + + # Create an interned copy. Take care to only keep a weak + # reference to the object itself. + def object_collected(obj): + kls._internable_stats.incr('collected') + # print("Object %s garbage collected" % obj) + pass + + ref = weakref.ref(self, object_collected) + kls._internable_dict[self] = ref + self._interned = True + kls._internable_stats.incr('inserted') + return self |