def main(output, *filenames): """ Generate a Perfect Hash Table for the Histogram name -> Histogram ID lookup. The table is immutable once generated and we can avoid any dynamic memory allocation. """ output.write(banner) output.write(header) try: histograms = list(parse_histograms.from_files(filenames)) histograms = [ h for h in histograms if h.record_on_os(buildconfig.substs["OS_TARGET"]) ] except ParserError as ex: print("\nError processing histograms:\n" + str(ex) + "\n") sys.exit(1) histograms = [(bytearray(hist.name(), 'ascii'), idx) for (idx, hist) in enumerate(histograms)] name_phf = PerfectHash(histograms, PHFSIZE) output.write( name_phf.cxx_codegen(name='HistogramIDByNameLookup', entry_type="uint32_t", lower_entry=lambda x: str(x[1]), key_type="const nsACString&", key_bytes="aKey.BeginReading()", key_length="aKey.Length()")) output.write(footer)
def main(output, *filenames): try: histograms = list(parse_histograms.from_files(filenames)) except ParserError as ex: print("\nError processing histograms:\n" + str(ex) + "\n") sys.exit(1) print(banner, file=output) write_histogram_table(output, histograms) write_histogram_ranges(output, histograms) write_histogram_static_asserts(output, histograms)
def test_current_histogram(self): HISTOGRAMS_PATH = path.join(TELEMETRY_ROOT_PATH, "Histograms.json") all_histograms = list( parse_histograms.from_files([HISTOGRAMS_PATH], strict_type_checks=False)) test_histogram = [ i for i in all_histograms if i.name() == 'TELEMETRY_TEST_FLAG' ][0] self.assertEqual(test_histogram.expiration(), 'never') self.assertEqual(test_histogram.kind(), 'flag') self.assertEqual(test_histogram.record_in_processes(), ["main", "content"]) self.assertEqual(test_histogram.keyed(), False)
def test_devtools_database_parsing(self): db = path.join(TELEMETRY_ROOT_PATH, path.pardir, path.pardir, path.pardir, "devtools", "shared", "css", "generated", "properties-db.js") histograms = list( parse_histograms.from_files([db], strict_type_checks=False)) histograms = [h.name() for h in histograms] # Test a shorthand (animation) self.assertTrue( "USE_COUNTER2_CSS_PROPERTY_Animation_DOCUMENT" in histograms) # Test a shorthand alias (-moz-animation). self.assertTrue( "USE_COUNTER2_CSS_PROPERTY_MozAnimation_DOCUMENT" in histograms) # Test a longhand (animation-name) self.assertTrue( "USE_COUNTER2_CSS_PROPERTY_AnimationName_DOCUMENT" in histograms) # Test a longhand alias (-moz-animation-name) self.assertTrue("USE_COUNTER2_CSS_PROPERTY_MozAnimationName_DOCUMENT" in histograms)
def main(output, *filenames): # Print header. print(banner, file=output) print(header, file=output) # Load the histograms. try: all_histograms = list(parse_histograms.from_files(filenames)) except ParserError as ex: print("\nError processing histograms:\n" + str(ex) + "\n") sys.exit(1) groups = itertools.groupby(all_histograms, get_histogram_typename) # Print the histogram enums. # Note that parse_histograms.py guarantees that all of the # USE_COUNTER2_*_WORKER and USE_COUNTER2_* histograms are both defined in a # contiguous block. print("enum HistogramID : uint32_t {", file=output) seen_group_types = {"UseCounter": False, "UseCounterWorker": False} for (group_type, histograms) in groups: if group_type is not None: assert isinstance(group_type, str) assert group_type in seen_group_types.keys() assert not seen_group_types[group_type] seen_group_types[group_type] = True # The Histogram*DUMMY enum variables are used to make the computation # of Histogram{First,Last}* easier. Otherwise, we'd have to special # case the first and last histogram in the group. print(" HistogramFirst%s," % group_type, file=output) print( " Histogram{0}DUMMY1 = HistogramFirst{0} - 1,".format( group_type), file=output, ) for histogram in histograms: if histogram.record_on_os(buildconfig.substs["OS_TARGET"]): print(" %s," % histogram.name(), file=output) if group_type is not None: assert isinstance(group_type, str) print(" Histogram%sDUMMY2," % group_type, file=output) print( " HistogramLast{0} = Histogram{0}DUMMY2 - 1,".format( group_type), file=output, ) print(" HistogramCount,", file=output) for (key, value) in sorted(seen_group_types.items()): if value: print( " Histogram{0}Count = HistogramLast{0} - HistogramFirst{0} + 1," .format(key), file=output, ) else: print(" HistogramFirst%s = 0," % key, file=output) print(" HistogramLast%s = 0," % key, file=output) print(" Histogram%sCount = 0," % key, file=output) print("};", file=output) # Write categorical label enums. categorical = filter(lambda h: h.kind() == "categorical", all_histograms) categorical = filter( lambda h: h.record_on_os(buildconfig.substs["OS_TARGET"]), categorical) enums = [("LABELS_" + h.name(), h.labels(), h.name()) for h in categorical] for name, labels, _ in enums: print("\nenum class %s : uint32_t {" % name, file=output) print(" %s" % ",\n ".join(labels), file=output) print("};", file=output) print( "\ntemplate<class T> struct IsCategoricalLabelEnum : std::false_type {};", file=output, ) for name, _, _ in enums: print( "template<> struct IsCategoricalLabelEnum<%s> : std::true_type {};" % name, file=output, ) print("\ntemplate<class T> struct CategoricalLabelId {};", file=output) for name, _, id in enums: print( "template<> struct CategoricalLabelId<%s> : " "std::integral_constant<uint32_t, %s> {};" % (name, id), file=output, ) # Footer. print(footer, file=output)
def main(output, *filenames): # Print header. print(banner, file=output) print(header, file=output) # Load the histograms. try: all_histograms = list(parse_histograms.from_files(filenames)) except ParserError as ex: print("\nError processing histograms:\n" + str(ex) + "\n") sys.exit(1) groups = itertools.groupby(all_histograms, lambda h: h.name().startswith("USE_COUNTER2_")) # Print the histogram enums. # Note that parse_histograms.py guarantees that all of the USE_COUNTER2_* # histograms are defined in a contiguous block. We therefore assume # that there's at most one group for which use_counter_group is true. print("enum HistogramID : uint32_t {", file=output) seen_use_counters = False for (use_counter_group, histograms) in groups: if use_counter_group: seen_use_counters = True # The HistogramDUMMY* enum variables are used to make the computation # of Histogram{First,Last}UseCounter easier. Otherwise, we'd have to # special case the first and last histogram in the group. if use_counter_group: print(" HistogramFirstUseCounter,", file=output) print(" HistogramDUMMY1 = HistogramFirstUseCounter - 1,", file=output) for histogram in histograms: if histogram.record_on_os(buildconfig.substs["OS_TARGET"]): print(" %s," % histogram.name(), file=output) if use_counter_group: print(" HistogramDUMMY2,", file=output) print(" HistogramLastUseCounter = HistogramDUMMY2 - 1,", file=output) print(" HistogramCount,", file=output) if seen_use_counters: print( " HistogramUseCounterCount = HistogramLastUseCounter -" " HistogramFirstUseCounter + 1", file=output) else: print(" HistogramFirstUseCounter = 0,", file=output) print(" HistogramLastUseCounter = 0,", file=output) print(" HistogramUseCounterCount = 0", file=output) print("};", file=output) # Write categorical label enums. categorical = filter(lambda h: h.kind() == "categorical", all_histograms) enums = [("LABELS_" + h.name(), h.labels(), h.name()) for h in categorical] for name, labels, _ in enums: print("\nenum class %s : uint32_t {" % name, file=output) print(" %s" % ",\n ".join(labels), file=output) print("};", file=output) print("\ntemplate<class T> struct IsCategoricalLabelEnum : FalseType {};", file=output) for name, _, _ in enums: print("template<> struct IsCategoricalLabelEnum<%s> : TrueType {};" % name, file=output) print("\ntemplate<class T> struct CategoricalLabelId {};", file=output) for name, _, id in enums: print("template<> struct CategoricalLabelId<%s> : " "IntegralConstant<uint32_t, %s> {};" % (name, id), file=output) # Footer. print(footer, file=output)