Compare commits
	
		
			1 Commits
		
	
	
		
			7538c6201b
			...
			bxinterval
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5f251e59e5 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					.coverage
 | 
				
			||||||
 | 
					*.pyc
 | 
				
			||||||
@@ -72,7 +72,7 @@ cdef class IntervalNode:
 | 
				
			|||||||
    cdef public object interval
 | 
					    cdef public object interval
 | 
				
			||||||
    cdef public double start, end
 | 
					    cdef public double start, end
 | 
				
			||||||
    cdef double minend, maxend, minstart
 | 
					    cdef double minend, maxend, minstart
 | 
				
			||||||
    cdef IntervalNode cleft, cright, croot
 | 
					    cdef public IntervalNode cleft, cright, croot
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    property left_node:
 | 
					    property left_node:
 | 
				
			||||||
        def __get__(self):
 | 
					        def __get__(self):
 | 
				
			||||||
@@ -390,6 +390,13 @@ cdef class IntervalTree:
 | 
				
			|||||||
    def __cinit__( self ):
 | 
					    def __cinit__( self ):
 | 
				
			||||||
        root = None
 | 
					        root = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Helper for plots
 | 
				
			||||||
 | 
					    def emptynode( self ):
 | 
				
			||||||
 | 
					        return EmptyNode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def rootnode( self ):
 | 
				
			||||||
 | 
					        return self.root
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # ---- Position based interfaces -----------------------------------------
 | 
					    # ---- Position based interfaces -----------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def insert( self, double start, double end, object value=None ):
 | 
					    def insert( self, double start, double end, object value=None ):
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										73
									
								
								tests/renderdot.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								tests/renderdot.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
				
			|||||||
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Renderer(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, getleft, getright,
 | 
				
			||||||
 | 
					                 getred, getstart, getend, nil):
 | 
				
			||||||
 | 
					        self.getleft = getleft
 | 
				
			||||||
 | 
					        self.getright = getright
 | 
				
			||||||
 | 
					        self.getred = getred
 | 
				
			||||||
 | 
					        self.getstart = getstart
 | 
				
			||||||
 | 
					        self.getend = getend
 | 
				
			||||||
 | 
					        self.nil = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Rendering
 | 
				
			||||||
 | 
					    def __render_dot_node(self, node, max_depth = 20):
 | 
				
			||||||
 | 
					        from nilmdb.printf import sprintf
 | 
				
			||||||
 | 
					        """Render a single node and its children into a dot graph fragment"""
 | 
				
			||||||
 | 
					        if max_depth == 0:
 | 
				
			||||||
 | 
					            return ""
 | 
				
			||||||
 | 
					        if node is self.nil:
 | 
				
			||||||
 | 
					            return ""
 | 
				
			||||||
 | 
					        def c(red):
 | 
				
			||||||
 | 
					            if red:
 | 
				
			||||||
 | 
					                return 'color="#ff0000", style=filled, fillcolor="#ffc0c0"'
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                return 'color="#000000", style=filled, fillcolor="#c0c0c0"'
 | 
				
			||||||
 | 
					        s = sprintf("%d [label=\"%g\\n%g\", %s];\n",
 | 
				
			||||||
 | 
					                    id(node),
 | 
				
			||||||
 | 
					                    self.getstart(node), self.getend(node),
 | 
				
			||||||
 | 
					                    c(self.getred(node)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.getleft(node) is self.nil:
 | 
				
			||||||
 | 
					            s += sprintf("L%d [label=\"-\", %s];\n", id(node), c(False))
 | 
				
			||||||
 | 
					            s += sprintf("%d -> L%d [label=L];\n", id(node), id(node))
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            s += sprintf("%d -> %d [label=L];\n",
 | 
				
			||||||
 | 
					                         id(node),id(self.getleft(node)))
 | 
				
			||||||
 | 
					        if self.getright(node) is self.nil:
 | 
				
			||||||
 | 
					            s += sprintf("R%d [label=\"-\", %s];\n", id(node), c(False))
 | 
				
			||||||
 | 
					            s += sprintf("%d -> R%d [label=R];\n", id(node), id(node))
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            s += sprintf("%d -> %d [label=R];\n",
 | 
				
			||||||
 | 
					                         id(node), id(self.getright(node)))
 | 
				
			||||||
 | 
					        s += self.__render_dot_node(self.getleft(node), max_depth-1)
 | 
				
			||||||
 | 
					        s += self.__render_dot_node(self.getright(node), max_depth-1)
 | 
				
			||||||
 | 
					        return s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def render_dot(self, rootnode, title = "Tree"):
 | 
				
			||||||
 | 
					        """Render the entire tree as a dot graph"""
 | 
				
			||||||
 | 
					        return ("digraph rbtree {\n"
 | 
				
			||||||
 | 
					                + self.__render_dot_node(rootnode)
 | 
				
			||||||
 | 
					                + "}\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def render_dot_live(self, rootnode, title = "Tree"):
 | 
				
			||||||
 | 
					        """Render the entiretree as a dot graph, live GTK view"""
 | 
				
			||||||
 | 
					        import gtk
 | 
				
			||||||
 | 
					        import gtk.gdk
 | 
				
			||||||
 | 
					        sys.path.append("/usr/share/xdot")
 | 
				
			||||||
 | 
					        import xdot
 | 
				
			||||||
 | 
					        xdot.Pen.highlighted = lambda pen: pen
 | 
				
			||||||
 | 
					        s = ("digraph rbtree {\n"
 | 
				
			||||||
 | 
					             + self.__render_dot_node(rootnode)
 | 
				
			||||||
 | 
					             + "}\n");
 | 
				
			||||||
 | 
					        window = xdot.DotWindow()
 | 
				
			||||||
 | 
					        window.set_dotcode(s)
 | 
				
			||||||
 | 
					        window.set_title(title + " - any key to close")
 | 
				
			||||||
 | 
					        window.connect('destroy', gtk.main_quit)
 | 
				
			||||||
 | 
					        def quit(widget, event):
 | 
				
			||||||
 | 
					            if not event.is_modifier:
 | 
				
			||||||
 | 
					                window.destroy()
 | 
				
			||||||
 | 
					                gtk.main_quit()
 | 
				
			||||||
 | 
					        window.widget.connect('key-press-event', quit)
 | 
				
			||||||
 | 
					        gtk.main()
 | 
				
			||||||
@@ -255,6 +255,47 @@ class TestInterval:
 | 
				
			|||||||
        for i in IntervalSet(iseta.intersection(Interval(125,250))):
 | 
					        for i in IntervalSet(iseta.intersection(Interval(125,250))):
 | 
				
			||||||
            assert(isinstance(i, DBInterval))
 | 
					            assert(isinstance(i, DBInterval))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestIntervalShape:
 | 
				
			||||||
 | 
					    def test_interval_shape(self):
 | 
				
			||||||
 | 
					        import random
 | 
				
			||||||
 | 
					        random.seed(1234)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # make a set of 500 intervals
 | 
				
			||||||
 | 
					        iset = IntervalSet()
 | 
				
			||||||
 | 
					        j = 500
 | 
				
			||||||
 | 
					        for i in random.sample(xrange(j),j):
 | 
				
			||||||
 | 
					            interval = Interval(i, i+1)
 | 
				
			||||||
 | 
					            iset += interval
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Plot it
 | 
				
			||||||
 | 
					        import renderdot
 | 
				
			||||||
 | 
					        r = renderdot.Renderer(lambda node: node.cleft,
 | 
				
			||||||
 | 
					                               lambda node: node.cright,
 | 
				
			||||||
 | 
					                               lambda node: False,
 | 
				
			||||||
 | 
					                               lambda node: node.start,
 | 
				
			||||||
 | 
					                               lambda node: node.end,
 | 
				
			||||||
 | 
					                               iset.tree.emptynode())
 | 
				
			||||||
 | 
					        r.render_dot_live(iset.tree.rootnode(), "Random")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # make a set of 500 intervals, inserted in order
 | 
				
			||||||
 | 
					        iset = IntervalSet()
 | 
				
			||||||
 | 
					        j = 500
 | 
				
			||||||
 | 
					        for i in xrange(j):
 | 
				
			||||||
 | 
					            interval = Interval(i, i+1)
 | 
				
			||||||
 | 
					            iset += interval
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Plot it
 | 
				
			||||||
 | 
					        import renderdot
 | 
				
			||||||
 | 
					        r = renderdot.Renderer(lambda node: node.cleft,
 | 
				
			||||||
 | 
					                               lambda node: node.cright,
 | 
				
			||||||
 | 
					                               lambda node: False,
 | 
				
			||||||
 | 
					                               lambda node: node.start,
 | 
				
			||||||
 | 
					                               lambda node: node.end,
 | 
				
			||||||
 | 
					                               iset.tree.emptynode())
 | 
				
			||||||
 | 
					        r.render_dot_live(iset.tree.rootnode(), "In-order")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert(False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestIntervalSpeed:
 | 
					class TestIntervalSpeed:
 | 
				
			||||||
    #@unittest.skip("this is slow")
 | 
					    #@unittest.skip("this is slow")
 | 
				
			||||||
    def test_interval_speed(self):
 | 
					    def test_interval_speed(self):
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user