#NEWLINE# def trim_dict( data , max_dict_bytes , percent = 50.0 , stepper_size = 10 , replace_with = 'VALUE_TRIMMED' , is_msgpacked = False , use_bin_type = False ) : #NEWLINE# #INDENT# '\n    Takes a dictionary and iterates over its keys, looking for\n    large values and replacing them with a trimmed string.\n\n    If after the first pass over dictionary keys, the dictionary\n    is not sufficiently small, the stepper_size will be increased\n    and the dictionary will be rescanned. This allows for progressive\n    scanning, removing large items first and only making additional\n    passes for smaller items if necessary.\n\n    This function uses msgpack to calculate the size of the dictionary\n    in question. While this might seem like unnecessary overhead, a\n    data structure in python must be serialized in order for sys.getsizeof()\n    to accurately return the items referenced in the structure.\n\n    Ex:\n    >>> salt.utils.trim_dict({\'a\': \'b\', \'c\': \'x\' * 10000}, 100)\n    {\'a\': \'b\', \'c\': \'VALUE_TRIMMED\'}\n\n    To improve performance, it is adviseable to pass in msgpacked\n    data structures instead of raw dictionaries. If a msgpack\n    structure is passed in, it will not be unserialized unless\n    necessary.\n\n    If a msgpack is passed in, it will be repacked if necessary\n    before being returned.\n\n    :param use_bin_type: Set this to true if "is_msgpacked=True"\n                         and the msgpack data has been encoded\n                         with "use_bin_type=True". This also means\n                         that the msgpack data should be decoded with\n                         "encoding=\'utf-8\'".\n    ' #NEWLINE# serializer = salt . payload . Serial ( { #NEWLINE# #INDENT# 'serial' : 'msgpack' , #NEWLINE# #UNINDENT# } ) #NEWLINE# if is_msgpacked : #NEWLINE# #INDENT# dict_size = sys . getsizeof ( data ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# dict_size = sys . getsizeof ( serializer . dumps ( data ) ) #NEWLINE# #UNINDENT# if ( dict_size > max_dict_bytes ) : #NEWLINE# #INDENT# if is_msgpacked : #NEWLINE# #INDENT# if use_bin_type : #NEWLINE# #INDENT# data = serializer . loads ( data , encoding = 'utf-8' ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# data = serializer . loads ( data ) #NEWLINE# #UNINDENT# #UNINDENT# while True : #NEWLINE# #INDENT# percent = float ( percent ) #NEWLINE# max_val_size = float ( ( max_dict_bytes * ( percent / 100 ) ) ) #NEWLINE# try : #NEWLINE# #INDENT# for key in data : #NEWLINE# #INDENT# if ( sys . getsizeof ( data [ key ] ) > max_val_size ) : #NEWLINE# #INDENT# data [ key ] = replace_with #NEWLINE# #UNINDENT# #UNINDENT# percent = ( percent - stepper_size ) #NEWLINE# max_val_size = float ( ( max_dict_bytes * ( dump_data / 100 ) ) ) #NEWLINE# if use_bin_type : #NEWLINE# #INDENT# dump_data = serializer . dumps ( data , use_bin_type = True ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# dump_data = serializer . dumps ( data ) #NEWLINE# #UNINDENT# cur_dict_size = sys . getsizeof ( dump_data ) #NEWLINE# if ( cur_dict_size < max_dict_bytes ) : #NEWLINE# #INDENT# if is_msgpacked : #NEWLINE# #INDENT# return dump_data #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# return data #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( max_val_size == 0 ) : #NEWLINE# #INDENT# if is_msgpacked : #NEWLINE# #INDENT# return dump_data #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# return data #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# except ValueError : #NEWLINE# #INDENT# pass #NEWLINE# #UNINDENT# #UNINDENT# if is_msgpacked : #NEWLINE# #INDENT# if use_bin_type : #NEWLINE# #INDENT# return serializer . dumps ( data , use_bin_type = True ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# return serializer . dumps ( data ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# return data #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# return data