12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#!/usr/bin/env python
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#coding:utf-8
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Author:  mozman -- <mozman@gmx.at>
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Purpose: TreeSlice
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Created: 11.04.2011
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Copyright (c) 2010-2013 by Manfred Moitzi
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# License: MIT License
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TreeSlice(object):
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    __slots__ = ['_tree', '_start', '_stop']
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    def __init__(self, tree, start, stop):
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        self._tree = tree
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        self._start = start
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        self._stop = stop
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    def __repr__(self):
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tpl = "%s({%s})" % (self._tree.__class__.__name__, '%s')
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return tpl % ", ".join( ("%r: %r" % item for item in self.items()) )
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    def __contains__(self, key):
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if self._inrange(key):
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return key in self._tree
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        else:
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return False
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    def _inrange(self, key):
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if self._start is not None and key < self._start:
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return False
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if self._stop is not None and key >= self._stop:
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return False
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return True
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    def __getitem__(self, key):
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if isinstance(key, slice):
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return self._subslice(key.start, key.stop)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if self._inrange(key):
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return self._tree[key]
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        else:
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raise KeyError(key)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    def _subslice(self, start, stop):
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        def newstart():
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            if start is None:
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return self._start
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            elif self._start is None:
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return start
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            else:
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return max(start, self._start)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        def newstop():
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            if stop is None:
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return self._stop
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            elif self._stop is None:
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return stop
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            else:
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return min(stop, self._stop)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return TreeSlice(self._tree, newstart(), newstop())
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    def keys(self):
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return self._tree.keyslice(self._start, self._stop)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    __iter__ = keys
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    def values(self):
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return self._tree.valueslice(self._start, self._stop)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    def items(self):
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return self._tree.itemslice(self._start, self._stop)
71