#!/usr/local/cpython-3.4/bin/python3

'''Generate the .dat files from the results database, for the sake of gnuplot'''

import dbm
import collections

import python2x3

class One_result_key(object):
    # pylint: disable=too-few-public-methods

    '''Store the data related to one result'''
    # b'cpython-3.4/sequential/binary_tree_dict/1024' b'0.14660346508026123'
    # b'cpython-2.7/sequential/avl_tree/1024' b'0.0459430217743'
    # b'pypy-2.4.0/random/b_tree/1024' b'0.08209800720215'
    # b'cpython-3.4/random/splay_tree/1024' b'0.017815113067626953'
    # b'cpython-3.4/random/scapegoat_tree_0_9/1024' b'0.018875837326049805'

    def __init__(self, byte_string):
        self.fields = byte_string.split(b'/')
        assert len(self.fields) == 4
        self.interpreter = self.fields[0]
        self.access_pattern = self.fields[1]
        assert self.access_pattern in {b'sequential', b'random'}
        self.datastructure = self.fields[2]
        self.size = int(self.fields[3])
        del self.fields[3]

    def __str__(self):
        return python2x3.binary_to_string(b'-'.join(self.fields))

    def __hash__(self):
        return sum((index + 1) * hash(element) for index, element in enumerate(self.fields))

    def __lt__(self, other):
        if self.fields < other.fields:
            return True
        else:
            return False

    def __eq__(self, other):
        if self.fields == other.fields:
            return True
        else:
            return False


class One_result_value(object):
    # pylint: disable=too-few-public-methods

    '''Store the data related to one result'''
    # b'cpython-3.4/sequential/binary_tree_dict/1024' b'0.14660346508026123'
    # b'cpython-2.7/sequential/avl_tree/1024' b'0.0459430217743'
    # b'pypy-2.4.0/random/b_tree/1024' b'0.08209800720215'
    # b'cpython-3.4/random/splay_tree/1024' b'0.017815113067626953'
    # b'cpython-3.4/random/scapegoat_tree_0_9/1024' b'0.018875837326049805'

    def __init__(self, byte_string, value):
        key_fields = byte_string.split(b'/')
        assert len(key_fields) == 4
        self.size = int(key_fields[3])

        value_fields = value.split(b' ')
        mean_duration = value_fields[0]
        standard_deviation_duration = value_fields[1]
        self.mean_duration = float(mean_duration)
        self.standard_deviation = float(standard_deviation_duration)

    def __str__(self):
        return python2x3.string_to_binary(self.mean_duration)

    def __lt__(self, other):
        if self.size < other.size:
            return True
        else:
            return False

    def __eq__(self, other):
        if self.size == other.size:
            return True
        else:
            return False


def main():
    '''Main function'''
    results_dict = collections.defaultdict(list)
    results_db = dbm.open('results', 'r')
    for key in results_db.keys():
        if results_db[key] != b'too_long':
            one_result_key = One_result_key(key)
            one_result_value = One_result_value(key, results_db[key])
            # The dictionary distinguishes based on hashes
            # Later we sort.
            results_dict[one_result_key].append(one_result_value)

    for key, values in results_dict.items():
        values.sort()
        with open('{}.dat'.format(key), 'w') as file_:
            for value in values:
                file_.write('{} {} {}\n'.format(value.size, value.mean_duration, value.standard_deviation))


main()