def analyze_symbol(l, sym, from_ver, to_ver, do_reads=False):
    """
    This is a utility function to produce text output with details about the versions of a given symbol.
    It is useful for debugging corruption issues and to mark corrupted versions.
    Parameters
    ----------
    l : `arctic.store.version_store.VersionStore`
        The VersionStore instance against which the analysis will be run.
    sym : `str`
        The symbol to analyze
    from_ver : `int` or `None`
        The lower bound for the version number we wish to analyze. If None then start from the earliest version.
    to_ver : `int` or `None`
        The upper bound for the version number we wish to analyze. If None then stop at the latest version.
    do_reads : `bool`
        If this flag is set to true, then the corruption check will actually try to read the symbol (slower).
    """
    logging.info('Analyzing symbol {}. Versions range is [v{}, v{}]'.format(sym, from_ver, to_ver))
    prev_rows = 0
    prev_n = 0
    prev_v = None

    logging.info('\nVersions for {}:'.format(sym))
    for v in l._versions.find({'symbol': sym, 'version': {'$gte': from_ver, '$lte': to_ver}},
                              sort=[('version', pymongo.ASCENDING)]):
        n = v.get('version')

        is_deleted = v.get('metadata').get('deleted', False) if v.get('metadata') else False

        if is_deleted:
            matching = 0
        else:
            spec = {'symbol': sym, 'parent': v.get('base_version_id', v['_id']), 'segment': {'$lt': v.get('up_to', 0)}}
            matching = mongo_count(l._collection, filter=spec) if not is_deleted else 0

        base_id = v.get('base_version_id')
        snaps = ['/'.join((str(x), str(x.generation_time))) for x in v.get('parent')] if v.get('parent') else None

        added_rows = v.get('up_to', 0) - prev_rows

        meta_match_with_prev = v.get('metadata') == prev_v.get('metadata') if prev_v else False

        delta_snap_creation = (min([x.generation_time for x in v.get('parent')]) - v['_id'].generation_time).total_seconds() / 60.0 if v.get('parent') else 0.0

        prev_v_diff = 0 if not prev_v else v['version'] - prev_v['version']

        corrupted = not is_deleted and (is_corrupted(l, sym, v) if do_reads else fast_is_corrupted(l, sym, v))

        logging.info(
            "v{: <6} "
            "{: <6} "
            "{: <5} "
            "({: <20}):   "
            "expected={: <6} "
            "found={: <6} "
            "last_row={: <10} "
            "new_rows={: <10} "
            "append count={: <10} "
            "append_size={: <10} "
            "type={: <14} {: <14} "
            "base={: <24}/{: <28} "
            "snap={: <30}[{:.1f} mins delayed] "
            "{: <20} "
            "{: <20}".format(
                n,
                prev_v_diff,
                'DEL' if is_deleted else 'ALIVE',
                str(v['_id'].generation_time),
                v.get('segment_count', 0),
                matching,
                v.get('up_to', 0),
                added_rows,
                v.get('append_count'),
                v.get('append_size'),
                v.get('type'),
                'meta-same' if meta_match_with_prev else 'meta-changed',
                str(base_id),
                str(base_id.generation_time) if base_id else '',
                str(snaps),
                delta_snap_creation,
                'PREV_MISSING' if prev_n < n - 1 else '',
                'CORRUPTED VERSION' if corrupted else '')
        )
        prev_rows = v.get('up_to', 0)
        prev_n = n
        prev_v = v

    logging.info('\nSegments for {}:'.format(sym))
    for seg in l._collection.find({'symbol': sym}, sort=[('_id', pymongo.ASCENDING)]):
        logging.info("{: <32}  {: <7}  {: <10} {: <30}".format(
            hashlib.sha1(seg['sha']).hexdigest(),
            seg.get('segment'),
            'compressed' if seg.get('compressed', False) else 'raw',
            str([str(p) for p in seg.get('parent', [])])
        ))
def analyze_symbol ( l , sym , from_ver , to_ver , do_reads = False ) : logging . info ( 'Analyzing symbol {}. Versions range is [v{}, v{}]' . format ( sym , from_ver , to_ver ) ) prev_rows = 0 prev_n = 0 prev_v = None logging . info ( '\nVersions for {}:' . format ( sym ) ) for v in l . _versions . find ( { 'symbol' : sym , 'version' : { '$gte' : from_ver , '$lte' : to_ver } } , sort = [ ( 'version' , pymongo . ASCENDING ) ] ) : n = v . get ( 'version' ) is_deleted = v . get ( 'metadata' ) . get ( 'deleted' , False ) if v . get ( 'metadata' ) else False if is_deleted : matching = 0 else : spec = { 'symbol' : sym , 'parent' : v . get ( 'base_version_id' , v [ '_id' ] ) , 'segment' : { '$lt' : v . get ( 'up_to' , 0 ) } } matching = mongo_count ( l . _collection , filter = spec ) if not is_deleted else 0 base_id = v . get ( 'base_version_id' ) snaps = [ '/' . join ( ( str ( x ) , str ( x . generation_time ) ) ) for x in v . get ( 'parent' ) ] if v . get ( 'parent' ) else None added_rows = v . get ( 'up_to' , 0 ) - prev_rows meta_match_with_prev = v . get ( 'metadata' ) == prev_v . get ( 'metadata' ) if prev_v else False delta_snap_creation = ( min ( [ x . generation_time for x in v . get ( 'parent' ) ] ) - v [ '_id' ] . generation_time ) . total_seconds ( ) / 60.0 if v . get ( 'parent' ) else 0.0 prev_v_diff = 0 if not prev_v else v [ 'version' ] - prev_v [ 'version' ] corrupted = not is_deleted and ( is_corrupted ( l , sym , v ) if do_reads else fast_is_corrupted ( l , sym , v ) ) logging . info ( "v{: <6} " "{: <6} " "{: <5} " "({: <20}):   " "expected={: <6} " "found={: <6} " "last_row={: <10} " "new_rows={: <10} " "append count={: <10} " "append_size={: <10} " "type={: <14} {: <14} " "base={: <24}/{: <28} " "snap={: <30}[{:.1f} mins delayed] " "{: <20} " "{: <20}" . format ( n , prev_v_diff , 'DEL' if is_deleted else 'ALIVE' , str ( v [ '_id' ] . generation_time ) , v . get ( 'segment_count' , 0 ) , matching , v . get ( 'up_to' , 0 ) , added_rows , v . get ( 'append_count' ) , v . get ( 'append_size' ) , v . get ( 'type' ) , 'meta-same' if meta_match_with_prev else 'meta-changed' , str ( base_id ) , str ( base_id . generation_time ) if base_id else '' , str ( snaps ) , delta_snap_creation , 'PREV_MISSING' if prev_n < n - 1 else '' , 'CORRUPTED VERSION' if corrupted else '' ) ) prev_rows = v . get ( 'up_to' , 0 ) prev_n = n prev_v = v logging . info ( '\nSegments for {}:' . format ( sym ) ) for seg in l . _collection . find ( { 'symbol' : sym } , sort = [ ( '_id' , pymongo . ASCENDING ) ] ) : logging . info ( "{: <32}  {: <7}  {: <10} {: <30}" . format ( hashlib . sha1 ( seg [ 'sha' ] ) . hexdigest ( ) , seg . get ( 'segment' ) , 'compressed' if seg . get ( 'compressed' , False ) else 'raw' , str ( [ str ( p ) for p in seg . get ( 'parent' , [ ] ) ] ) ) )
This is a utility function to produce text output with details about the versions of a given symbol.
    It is useful for debugging corruption issues and to mark corrupted versions.
    Parameters
    ----------
    l : `arctic.store.version_store.VersionStore`
        The VersionStore instance against which the analysis will be run.
    sym : `str`
        The symbol to analyze
    from_ver : `int` or `None`
        The lower bound for the version number we wish to analyze. If None then start from the earliest version.
    to_ver : `int` or `None`
        The upper bound for the version number we wish to analyze. If None then stop at the latest version.
    do_reads : `bool`
        If this flag is set to true, then the corruption check will actually try to read the symbol (slower).