from libtree.tree import insert_node
from time import time

RUNS = (
    (1, 500),
    (1, 1000),
    (1, 10000),
    ##(1, 100000),
    ##(1, 1000000)
    (2, 100),
    ##(2, 200),
    ##(2, 500),
    (3, 25),
    (3, 35),
    (4, 10),
    (5, 8),
    #(5, 10),
    (6, 6),
    (7, 5),
    (8, 4),
    (9, 3),
    (10, 3),
    (11, 2),
    (12, 2),
    (15, 2),
    #(17, 2),
    ##(20, 2)
)

stats = list()
averages = list()
average = lambda a: sum(a) / len(a)


def calculate_tree_size(levels, per_level):
    return int(((1 - per_level ** (levels + 1)) / (1 - per_level)) - 1)


def populate_tree(per, node, levels, per_level, auto_position, depth=1):
    global stats
    for i in range(0, per_level):
        start = time()
        new_node = insert_node(per, node, auto_position=auto_position)
        duration = (time() - start) * 1000
        stats.append(duration)

        if depth < levels:
            populate_tree(per, new_node, levels, per_level, auto_position,
                          depth+1)


def benchmark(per, levels, per_level, auto_position):
    global stats, averages
    stats = list()
    root = insert_node(per, None, 'root')

    start = time()
    populate_tree(per, root, levels, per_level, auto_position)
    duration = time() - start

    start = time()
    per.commit()
    duration_commit = (time() - start) * 1000

    output = '=> {:.4f}ms per node, {:.4f}s total, {:.4f}ms commit time'
    _average = average(stats)
    print(output.format(_average, duration, duration_commit))
    #print(len(stats))
    averages.append(_average)


def setup(per):
    pass


def run(per):
    print('auto position OFF')
    for levels, per_level in RUNS:
        per.flush_tables()
        per.commit()
        output = '{} levels, {:,} nodes per level ({:,} nodes total)...'
        print(output.format(levels, per_level,
                            calculate_tree_size(levels, per_level)))
        benchmark(per, levels, per_level, False)
    output = 'Average insertion speed (auto position off): {:.4f}ms'
    print(output.format(average(averages)))

    print()
    print('auto position ON')
    for levels, per_level in RUNS:
        per.flush_tables()
        per.commit()
        output = '{} levels, {:,} nodes per level ({:,} nodes total)...'
        print(output.format(levels, per_level,
                            calculate_tree_size(levels, per_level)))
        benchmark(per, levels, per_level, True)
    output = 'Average insertion speed (auto position on): {:.4f}ms'
    print(output.format(average(averages)))



@@ -51,16 +51,58 @@
 ort time
+%0Aimport sys%0A%0A%0Asys.setrecursionlimit(15000)
 %0A%0ARUNS =
@@ -420,17 +420,61 @@
     
-##
 (20, 
-2)
+1),%0A    (200, 1),%0A    (2000, 1),%0A    (10000, 1),
 %0A)%0A%0A
@@ -584,24 +584,69 @@
 per_level):%0A
+    if per_level == 1:%0A        return levels%0A
     return i
@@ -1864,32 +1864,34 @@
      output = '%7B
+:,
 %7D levels, %7B:,%7D n

allow for 1 node per level in insertion benchmark