from gi.repository import GExiv2

class MemoizedMetadata(GExiv2.Metadata):
    def __init__(self, *args, **kwargs):
        super(MemoizedMetadata, self).__init__(*args, **kwargs)

        self._metadata = {}
        self._metadata.update(self.get_xmp_tags_string())
        self._metadata.update(self.get_exif_tags_string())
        self._metadata.update(self.get_iptc_tags_string())

    def get_tags(self):
        return self._metadata.keys()

    def __getitem__(self, key):
        try:
            return self._metadata[key]
        except KeyError:
            return super(MemoizedMetadata, self).__getitem__(key)

    def __setitem__(self, key, value):
        super(MemoizedMetadata, self).__setitem__(key, value)
        self._metadata[key] = value

    def __delitem__(self, key):
        super(MemoizedMetadata, self).__delitem__(key)
        del self._metadata[key]

def read_tags():
    meta = GExiv2.Metadata('/tmp/test.dng')
    for t in meta.get_tags():
        # Dummy lookup
        meta[t]

def read_tags_memoized():
    meta = MemoizedMetadata('/tmp/test.dng')
    for t in meta.get_tags():
        # Dummy lookup
        meta[t]

if __name__ == "__main__":
    import timeit

    iterations = 100

    total = timeit.timeit("read_tags()", number=iterations,
        setup="from gi.repository import GExiv2; from __main__ import read_tags")

    memoized_total = timeit.timeit("read_tags_memoized()", number=iterations,
        setup="from benchmark import read_tags_memoized, MemoizedMetadata")

    print "Average: %fms" % (total/iterations * 1000)
    print "Memoized Average: %fms" % (memoized_total/iterations * 1000)
