# Path: lsh/utils/similarity.py
# def compute_positive_hash(value):
#     return hash(value) % ((sys.maxsize + 1) * 2)
# 
# Path: lsh/shingles/shingles.py
# def _get_list_of_shingles(doc, size=DEFAULT_SHINGLE_SIZE):
#     """
#         Creates a list of shingles (strings)
#         :param doc: doc to create shingles from
#         :type doc: string
#         :param size: size of shingle
#         :type size: int
#         :return: list of shingles (strings), will return an empty list if doc is None or empty
#     """
# 
#     if doc:
#         return [doc[i:i + size] for i in range(len(doc) - size + 1)]
#     else:
#         return []
# 
# Path: repositories/gae/dataset.py
# def get_random_bits(max_hashes):
#     return [random.getrandbits(get_max_bits()) for _ in xrange(max_hashes)]
# 
# def calculate_max_hashes(rows, bands):
#     return rows * bands


import operator, struct, math, sys, logging, datetime
from lsh.utils.similarity import compute_positive_hash
from lsh.shingles.shingles import _get_list_of_shingles
from repositories.gae.dataset import get_random_bits, calculate_max_hashes
        logging.info('id %s, length %d, time %d', id, len(text), int((end-start).total_seconds()))

    for bkt in buckets:
        yield (bkt, '/view/%s/%s' % (dataset.filename, id))

def reduce(key, values):
    logging.info("OpenLSH > reduce() called.")
    yield (key, values)

#TODO Create single methods for the lsh code below and one driver function to call

#LSH functions for calculating minhash signatures, creating list of shingles
def calc_minhashes(parsed_text, sh_type, hashes, seeds, modulo):
    def minhashes_for_shingles(shingles, sh_type, hashes, seeds, modulo):
        def calc_onehash(sh_type, shingle, seed, modulo):
            def c4_hash(shingle):
                h = struct.unpack('<i',shingle)[0]
                return  h % ((sys.maxsize + 1) * 2)
            if sh_type == 'c4':
                return operator.xor(c4_hash(shingle), long(seed)) % modulo
            else:
                return operator.xor(compute_positive_hash(shingle), long(seed)) % modulo

        minhashes = [sys.maxsize for _ in xrange(hashes)]
        for shingle in shingles:
            for hno in xrange(hashes):
                h_value = calc_onehash(sh_type, shingle, seeds[hno], modulo)
                minhashes[hno] = min(h_value, minhashes[hno])
        return minhashes


# Path: lsh/utils/similarity.py
# def compute_positive_hash(value):
#     return hash(value) % ((sys.maxsize + 1) * 2)
# 
# Path: lsh/shingles/shingles.py
# def _get_list_of_shingles(doc, size=DEFAULT_SHINGLE_SIZE):
#     """
#         Creates a list of shingles (strings)
#         :param doc: doc to create shingles from
#         :type doc: string
#         :param size: size of shingle
#         :type size: int
#         :return: list of shingles (strings), will return an empty list if doc is None or empty
#     """
# 
#     if doc:
#         return [doc[i:i + size] for i in range(len(doc) - size + 1)]
#     else:
#         return []
# 
# Path: repositories/gae/dataset.py
# def get_random_bits(max_hashes):
#     return [random.getrandbits(get_max_bits()) for _ in xrange(max_hashes)]
# 
# def calculate_max_hashes(rows, bands):
#     return rows * bands


# Path: lsh/gae/map_reduce.py
import operator, struct, math, sys, logging, datetime
from lsh.utils.similarity import compute_positive_hash
from lsh.shingles.shingles import _get_list_of_shingles
from repositories.gae.dataset import get_random_bits, calculate_max_hashes

        logging.info('id %s, length %d, time %d', id, len(text), int((end-start).total_seconds()))

    for bkt in buckets:
        yield (bkt, '/view/%s/%s' % (dataset.filename, id))

def reduce(key, values):
    logging.info("OpenLSH > reduce() called.")
    yield (key, values)

#TODO Create single methods for the lsh code below and one driver function to call

#LSH functions for calculating minhash signatures, creating list of shingles
def calc_minhashes(parsed_text, sh_type, hashes, seeds, modulo):
    def minhashes_for_shingles(shingles, sh_type, hashes, seeds, modulo):
        def calc_onehash(sh_type, shingle, seed, modulo):
            def c4_hash(shingle):
                h = struct.unpack('<i',shingle)[0]
                return  h % ((sys.maxsize + 1) * 2)
            if sh_type == 'c4':
                return operator.xor(c4_hash(shingle), long(seed)) % modulo
            else:
                return operator.xor(compute_positive_hash(shingle), long(seed)) % modulo

        minhashes = [sys.maxsize for _ in xrange(hashes)]
        for shingle in shingles:
            for hno in xrange(hashes):
                h_value = calc_onehash(sh_type, shingle, seeds[hno], modulo)
                minhashes[hno] = min(h_value, minhashes[hno])
        return minhashes


    shingles = parsed_text.split() if sh_type=='w' else set(_get_list_of_shingles(parsed_text))