def find(self, rel, key):
        """
        Searches for a record with the specified relation to the key

        A cursor object is returned, the user can call getkey, getval on the cursor
        to retrieve the actual value.
        or call cursor.next() / cursor.prev() to enumerate values.

        'eq'  -> record equal to the key, None when not found
        'le'  -> last record with key <= to key
        'ge'  -> first record with key >= to key
        'lt'  -> last record with key < to key
        'gt'  -> first record with key > to key
        """

        # descend tree to leaf nearest to the `key`
        page = self.readpage(self.firstindex)
        stack = []
        while len(stack) < 256:
            act, ix = page.find(key)
            stack.append((page, ix))
            if act != 'recurse':
                break
            page = self.readpage(page.getpage(ix))

        if len(stack) == 256:
            raise Exception("b-tree corrupted")
        cursor = BTree.Cursor(self, stack)

        # now correct for what was actually asked.
        if act == rel:
            pass
        elif rel == 'eq' and act != 'eq':
            return None
        elif rel in ('ge', 'le') and act == 'eq':
            pass
        elif rel in ('gt', 'ge') and act == 'lt':
            cursor.next()
        elif rel == 'gt' and act == 'eq':
            cursor.next()
        elif rel in ('lt', 'le') and act == 'gt':
            cursor.prev()
        elif rel == 'lt' and act == 'eq':
            cursor.prev()

        return cursor