# Path: subspace/utils.py
# class OrderedSet(list):
#     """
#     Acts like a list in all ways, except in the behavior of the :meth:`push` method.
#     """
# 
#     def push(self, thing):
#         """
#         1. If the item exists in the list, it's removed
#         2. The item is pushed to the end of the list
#         """
#         if thing in self:
#             self.remove(thing)
#         self.append(thing)
# 
# def sharedPrefix(args):
#     """
#     Find the shared prefix between the strings.
# 
#     For instance:
# 
#         sharedPrefix(['blahblah', 'blahwhat'])
# 
#     returns 'blah'.
#     """
#     i = 0
#     while i < min(map(len, args)):
#         if len(set(map(operator.itemgetter(i), args))) != 1:
#             break
#         i += 1
#     return args[0][:i]


import heapq
import time
import operator
from collections import OrderedDict
from subspace.utils import OrderedSet, sharedPrefix
        del self.nodes[node.id]
        if len(self.replacementNodes) > 0:
            newnode = self.replacementNodes.pop()
            self.nodes[newnode.id] = newnode

    def hasInRange(self, node):
        return self.range[0] <= node.long_id <= self.range[1]

    def isNewNode(self, node):
        return node.id not in self.nodes

    def addNode(self, node):
        """
        Add a C{Node} to the C{KBucket}.  Return True if successful,
        False if the bucket is full.

        If the bucket is full, keep track of node in a replacement list,
        per section 4.1 of the paper.
        """
        if node.id in self.nodes:
            del self.nodes[node.id]
            self.nodes[node.id] = node
        elif len(self) < self.ksize:
            self.nodes[node.id] = node
        else:
            self.replacementNodes.push(node)
            return False
        return True

    def depth(self):

# Path: subspace/utils.py
# class OrderedSet(list):
#     """
#     Acts like a list in all ways, except in the behavior of the :meth:`push` method.
#     """
# 
#     def push(self, thing):
#         """
#         1. If the item exists in the list, it's removed
#         2. The item is pushed to the end of the list
#         """
#         if thing in self:
#             self.remove(thing)
#         self.append(thing)
# 
# def sharedPrefix(args):
#     """
#     Find the shared prefix between the strings.
# 
#     For instance:
# 
#         sharedPrefix(['blahblah', 'blahwhat'])
# 
#     returns 'blah'.
#     """
#     i = 0
#     while i < min(map(len, args)):
#         if len(set(map(operator.itemgetter(i), args))) != 1:
#             break
#         i += 1
#     return args[0][:i]


# Path: subspace/routing.py
import heapq
import time
import operator
from collections import OrderedDict
from subspace.utils import OrderedSet, sharedPrefix

        del self.nodes[node.id]
        if len(self.replacementNodes) > 0:
            newnode = self.replacementNodes.pop()
            self.nodes[newnode.id] = newnode

    def hasInRange(self, node):
        return self.range[0] <= node.long_id <= self.range[1]

    def isNewNode(self, node):
        return node.id not in self.nodes

    def addNode(self, node):
        """
        Add a C{Node} to the C{KBucket}.  Return True if successful,
        False if the bucket is full.

        If the bucket is full, keep track of node in a replacement list,
        per section 4.1 of the paper.
        """
        if node.id in self.nodes:
            del self.nodes[node.id]
            self.nodes[node.id] = node
        elif len(self) < self.ksize:
            self.nodes[node.id] = node
        else:
            self.replacementNodes.push(node)
            return False
        return True

    def depth(self):

        sp = sharedPrefix([n.id for n in self.nodes.values()])