Compare commits

...

1 Commits

Author SHA1 Message Date
5f251e59e5 Render layout of bxintersect 2012-11-28 17:17:44 -05:00
4 changed files with 124 additions and 1 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.coverage
*.pyc

View File

@ -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
View 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()

View File

@ -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):