def write_user_interaction_table(user_interactions, output, string_table): head = """ namespace mozilla { namespace Telemetry { namespace UserInteractionID { const static uint32_t UserInteractionCount = %d; } // namespace UserInteractionID } // namespace Telemetry } // namespace mozilla """ print(head % len(user_interactions), file=output) print("namespace {", file=output) table_name = "gUserInteractions" print("constexpr UserInteractionInfo %s[] = {" % table_name, file=output) for u in user_interactions: name_index = string_table.stringIndex(u.label) print(" UserInteractionInfo({}),".format(name_index), file=output) print("};", file=output) static_assert( output, "sizeof(%s) <= UINT32_MAX" % table_name, "index overflow of UserInteractionInfo table %s" % table_name, ) print("} // namespace", file=output)
def main(output, *filenames): # Load the UserInteraction data. user_interactions = [] for filename in filenames: try: batch = parse_user_interactions.load_user_interactions(filename) user_interactions.extend(batch) except ParserError as ex: print("\nError processing %s:\n%s\n" % (filename, str(ex)), file=sys.stderr) sys.exit(1) # Write the scalar data file. print(banner, file=output) print(file_header, file=output) string_table = StringTable() # Write the data for individual UserInteractions. write_user_interaction_table(user_interactions, output, string_table) print("", file=output) # Write the string table. string_table_name = "gUserInteractionsStringTable" string_table.writeDefinition(output, string_table_name) static_assert( output, "sizeof(%s) <= UINT32_MAX" % string_table_name, "index overflow" ) print("", file=output) print(file_footer, file=output)
def write_extra_table(events, output, string_table): table_name = "gExtraKeysTable" extra_table = [] extra_count = 0 print("#if defined(_MSC_VER) && !defined(__clang__)", file=output) print("const uint32_t %s[] = {" % table_name, file=output) print("#else", file=output) print("constexpr uint32_t %s[] = {" % table_name, file=output) print("#endif", file=output) for e in events: extra_index = 0 extra_keys = e.extra_keys if len(extra_keys) > 0: extra_index = extra_count extra_count += len(extra_keys) indexes = string_table.stringIndexes(extra_keys) print(" // %s, [%s], [%s]" % (e.category, ", ".join(e.methods), ", ".join(e.objects)), file=output) print(" // extra_keys: %s" % ", ".join(extra_keys), file=output) print(" %s," % ", ".join(map(str, indexes)), file=output) extra_table.append((extra_index, len(extra_keys))) print("};", file=output) static_assert(output, "sizeof(%s) <= UINT32_MAX" % table_name, "index overflow") return extra_table
def write_common_event_table(events, output, string_table, extra_table): table_name = "gCommonEventInfo" print("#if defined(_MSC_VER) && !defined(__clang__)", file=output) print("const CommonEventInfo %s[] = {" % table_name, file=output) print("#else", file=output) print("constexpr CommonEventInfo %s[] = {" % table_name, file=output) print("#endif", file=output) for e, extras in zip(events, extra_table): # Write a comment to make the file human-readable. print(" // category: %s" % e.category, file=output) print(" // methods: [%s]" % ", ".join(e.methods), file=output) print(" // objects: [%s]" % ", ".join(e.objects), file=output) # Write the common info structure print( " {%d, %d, %d, %d, %s, %s, %s }," % ( string_table.stringIndex(e.category), string_table.stringIndex(e.expiry_version), extras[0], # extra keys index extras[1], # extra keys count e.dataset, " | ".join(e.record_in_processes_enum), " | ".join(e.products_enum)), file=output) print("};", file=output) static_assert(output, "sizeof(%s) <= UINT32_MAX" % table_name, "index overflow")
def write_event_table(events, output, string_table): table_name = "gEventInfo" print("#if defined(_MSC_VER) && !defined(__clang__)", file=output) print("const EventInfo %s[] = {" % table_name, file=output) print("#else", file=output) print("constexpr EventInfo %s[] = {" % table_name, file=output) print("#endif", file=output) for common_info_index, e in enumerate(events): for method_name, object_name in itertools.product( e.methods, e.objects): print( " // category: %s, method: %s, object: %s" % (e.category, method_name, object_name), file=output, ) print( " {gCommonEventInfo[%d], %d, %d}," % ( common_info_index, string_table.stringIndex(method_name), string_table.stringIndex(object_name), ), file=output, ) print("};", file=output) static_assert(output, "sizeof(%s) <= UINT32_MAX" % table_name, "index overflow")
def main(output, *filenames): # Load the event data. if len(filenames) > 1: raise Exception('We don\'t support loading from more than one file.') try: events = parse_events.load_events(filenames[0], True) except ParserError as ex: print("\nError processing events:\n" + str(ex) + "\n") sys.exit(1) # Write the scalar data file. print(banner, file=output) print(file_header, file=output) # Write the extra keys table. string_table = StringTable() extra_table = write_extra_table(events, output, string_table) print("", file=output) # Write a table with the common event data. write_common_event_table(events, output, string_table, extra_table) print("", file=output) # Write the data for individual events. write_event_table(events, output, string_table) print("", file=output) # Write the string table. string_table_name = "gEventsStringTable" string_table.writeDefinition(output, string_table_name) static_assert(output, "sizeof(%s) <= UINT32_MAX" % string_table_name, "index overflow") print("", file=output) print(file_footer, file=output)
def write_histogram_table(output, histograms): string_table = StringTable() label_table = [] label_count = 0 keys_table = [] keys_count = 0 print("constexpr HistogramInfo gHistogramInfos[] = {", file=output) for histogram in histograms: name_index = string_table.stringIndex(histogram.name()) exp_index = string_table.stringIndex(histogram.expiration()) labels = histogram.labels() label_index = 0 if len(labels) > 0: label_index = label_count label_table.append( (histogram.name(), string_table.stringIndexes(labels))) label_count += len(labels) keys = histogram.keys() key_index = 0 if len(keys) > 0: key_index = keys_count keys_table.append( (histogram.name(), string_table.stringIndexes(keys))) keys_count += len(keys) print_array_entry(output, histogram, name_index, exp_index, label_index, len(labels), key_index, len(keys)) print("};\n", file=output) strtab_name = "gHistogramStringTable" string_table.writeDefinition(output, strtab_name) static_assert(output, "sizeof(%s) <= UINT32_MAX" % strtab_name, "index overflow") print("\n#if defined(_MSC_VER) && !defined(__clang__)", file=output) print("const uint32_t gHistogramLabelTable[] = {", file=output) print("#else", file=output) print("constexpr uint32_t gHistogramLabelTable[] = {", file=output) print("#endif", file=output) for name, indexes in label_table: print("/* %s */ %s," % (name, ", ".join(map(str, indexes))), file=output) print("};", file=output) print("\n#if defined(_MSC_VER) && !defined(__clang__)", file=output) print("const uint32_t gHistogramKeyTable[] = {", file=output) print("#else", file=output) print("constexpr uint32_t gHistogramKeyTable[] = {", file=output) print("#endif", file=output) for name, indexes in keys_table: print("/* %s */ %s," % (name, ", ".join(map(str, indexes))), file=output) print("};", file=output)
def write_scalar_tables(scalars, output): """Writes the scalar and strings tables to an header file. :param scalars: a list of ScalarType instances describing the scalars. :param output: the output stream. """ string_table = StringTable() store_table = [] total_store_count = 0 print("const ScalarInfo gScalars[] = {", file=output) for s in scalars: # We add both the scalar label and the expiration string to the strings # table. name_index = string_table.stringIndex(s.label) exp_index = string_table.stringIndex(s.expires) stores = s.record_into_store store_index = 0 if stores == ["main"]: # if count == 1 && offset == UINT16_MAX -> only main store store_index = 'UINT16_MAX' else: store_index = total_store_count store_table.append((s.label, string_table.stringIndexes(stores))) total_store_count += len(stores) # Write the scalar info entry. write_scalar_info(s, output, name_index, exp_index, store_index, len(stores)) print("};", file=output) string_table_name = "gScalarsStringTable" string_table.writeDefinition(output, string_table_name) static_assert(output, "sizeof(%s) <= UINT32_MAX" % string_table_name, "index overflow") store_table_name = "gScalarStoresTable" print("\n#if defined(_MSC_VER) && !defined(__clang__)", file=output) print("const uint32_t {}[] = {{".format(store_table_name), file=output) print("#else", file=output) print("constexpr uint32_t {}[] = {{".format(store_table_name), file=output) print("#endif", file=output) for name, indexes in store_table: print("/* %s */ %s," % (name, ", ".join(map(str, indexes))), file=output) print("};", file=output) static_assert(output, "sizeof(%s) <= UINT16_MAX" % store_table_name, "index overflow")
def shared_static_asserts(output, histogram): name = histogram.name() low = histogram.low() high = histogram.high() n_buckets = histogram.n_buckets() static_assert(output, "%s < %s" % (low, high), "low >= high for %s" % name) static_assert(output, "%s > 2" % n_buckets, "Not enough values for %s" % name) static_assert(output, "%s >= 1" % low, "Incorrect low value for %s" % name) static_assert( output, "%s > %s" % (high, n_buckets), "high must be > number of buckets for %s;" " you may want an enumerated histogram" % name)
def write_scalar_tables(scalars, output): """Writes the scalar and strings tables to an header file. :param scalars: a list of ScalarType instances describing the scalars. :param output: the output stream. """ string_table = StringTable() print("const ScalarInfo gScalars[] = {", file=output) for s in scalars: # We add both the scalar label and the expiration string to the strings # table. name_index = string_table.stringIndex(s.label) exp_index = string_table.stringIndex(s.expires) # Write the scalar info entry. write_scalar_info(s, output, name_index, exp_index) print("};", file=output) string_table_name = "gScalarsStringTable" string_table.writeDefinition(output, string_table_name) static_assert(output, "sizeof(%s) <= UINT32_MAX" % string_table_name, "index overflow")
def main(output, *filenames): # Load the event data. events = [] for filename in filenames: try: batch = parse_events.load_events(filename, True) events.extend(batch) except ParserError as ex: print("\nError processing %s:\n%s\n" % (filename, str(ex)), file=sys.stderr) sys.exit(1) # Write the scalar data file. print(banner, file=output) print(file_header, file=output) # Write the extra keys table. string_table = StringTable() extra_table = write_extra_table(events, output, string_table) print("", file=output) # Write a table with the common event data. write_common_event_table(events, output, string_table, extra_table) print("", file=output) # Write the data for individual events. write_event_table(events, output, string_table) print("", file=output) # Write the string table. string_table_name = "gEventsStringTable" string_table.writeDefinition(output, string_table_name) static_assert(output, "sizeof(%s) <= UINT32_MAX" % string_table_name, "index overflow") print("", file=output) print(file_footer, file=output)
def static_asserts_for_enumerated(output, histogram): n_values = histogram.high() static_assert(output, "%s > 2" % n_values, "Not enough values for %s" % histogram.name())
def write_histogram_table(output, histograms): string_table = StringTable() label_table = [] label_count = 0 keys_table = [] keys_count = 0 store_table = [] total_store_count = 0 print("constexpr HistogramInfo gHistogramInfos[] = {", file=output) for histogram in histograms: name_index = string_table.stringIndex(histogram.name()) exp_index = string_table.stringIndex(histogram.expiration()) labels = histogram.labels() label_index = 0 if len(labels) > 0: label_index = label_count label_table.append( (histogram.name(), string_table.stringIndexes(labels))) label_count += len(labels) keys = histogram.keys() key_index = 0 if len(keys) > 0: key_index = keys_count keys_table.append( (histogram.name(), string_table.stringIndexes(keys))) keys_count += len(keys) stores = histogram.record_into_store() store_index = 0 if stores == ["main"]: # if count == 1 && offset == UINT16_MAX -> only main store store_index = "UINT16_MAX" else: store_index = total_store_count store_table.append( (histogram.name(), string_table.stringIndexes(stores))) total_store_count += len(stores) print_array_entry( output, histogram, name_index, exp_index, label_index, len(labels), key_index, len(keys), store_index, len(stores), ) print("};\n", file=output) strtab_name = "gHistogramStringTable" string_table.writeDefinition(output, strtab_name) static_assert(output, "sizeof(%s) <= UINT32_MAX" % strtab_name, "index overflow") print("\n#if defined(_MSC_VER) && !defined(__clang__)", file=output) print("const uint32_t gHistogramLabelTable[] = {", file=output) print("#else", file=output) print("constexpr uint32_t gHistogramLabelTable[] = {", file=output) print("#endif", file=output) for name, indexes in label_table: print("/* %s */ %s," % (name, ", ".join(map(str, indexes))), file=output) print("};", file=output) static_assert(output, "sizeof(gHistogramLabelTable) <= UINT16_MAX", "index overflow") print("\n#if defined(_MSC_VER) && !defined(__clang__)", file=output) print("const uint32_t gHistogramKeyTable[] = {", file=output) print("#else", file=output) print("constexpr uint32_t gHistogramKeyTable[] = {", file=output) print("#endif", file=output) for name, indexes in keys_table: print("/* %s */ %s," % (name, ", ".join(map(str, indexes))), file=output) print("};", file=output) static_assert(output, "sizeof(gHistogramKeyTable) <= UINT16_MAX", "index overflow") store_table_name = "gHistogramStoresTable" print("\n#if defined(_MSC_VER) && !defined(__clang__)", file=output) print("const uint32_t {}[] = {{".format(store_table_name), file=output) print("#else", file=output) print("constexpr uint32_t {}[] = {{".format(store_table_name), file=output) print("#endif", file=output) for name, indexes in store_table: print("/* %s */ %s," % (name, ", ".join(map(str, indexes))), file=output) print("};", file=output) static_assert(output, "sizeof(%s) <= UINT16_MAX" % store_table_name, "index overflow")