scenario.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. # Copyright Materialize, Inc. and contributors. All rights reserved.
  2. #
  3. # Use of this software is governed by the Business Source License
  4. # included in the LICENSE file at the root of this repository.
  5. #
  6. # As of the Change Date specified in that file, in accordance with
  7. # the Business Source License, use of this software will be governed
  8. # by the Apache License, Version 2.0.
  9. from math import ceil
  10. from materialize.feature_benchmark.action import Action, DummyAction, TdAction
  11. from materialize.feature_benchmark.measurement import MeasurementType
  12. from materialize.feature_benchmark.measurement_source import MeasurementSource
  13. from materialize.feature_benchmark.scenario_version import ScenarioVersion
  14. from materialize.mz_version import MzVersion
  15. BenchmarkingSequence = MeasurementSource | list[Action | MeasurementSource]
  16. class RootScenario:
  17. SCALE: float = 6
  18. FIXED_SCALE: bool = False # Will --scale=N have effect on the scenario
  19. RELATIVE_THRESHOLD: dict[MeasurementType, float] = {
  20. MeasurementType.WALLCLOCK: 0.10,
  21. # Increased the other measurements since they are easy to regress now
  22. # that we take the run with the minimum wallclock time:
  23. MeasurementType.MEMORY_MZ: 0.20,
  24. MeasurementType.MEMORY_CLUSTERD: 0.50,
  25. }
  26. def __init__(
  27. self, scale: float, mz_version: MzVersion, default_size: int, seed: int
  28. ) -> None:
  29. self._name = self.__class__.__name__
  30. self._scale = scale
  31. self._mz_version = mz_version
  32. self._n: int = int(10**scale)
  33. self._default_size = default_size
  34. self._seed = seed
  35. @classmethod
  36. def can_run(cls, version: MzVersion) -> bool:
  37. return True
  38. def shared(self) -> Action | list[Action] | None:
  39. return None
  40. def init(self) -> Action | list[Action] | None:
  41. return None
  42. def before(self) -> Action | list[Action] | None:
  43. return DummyAction()
  44. def benchmark(self) -> BenchmarkingSequence:
  45. raise NotImplementedError
  46. def name(self) -> str:
  47. return self._name
  48. def version(self) -> ScenarioVersion:
  49. return ScenarioVersion.create(1, 0, 0)
  50. def scale(self) -> float:
  51. return self._scale
  52. def n(self) -> int:
  53. return self._n
  54. def seed(self) -> int:
  55. return self._seed
  56. @staticmethod
  57. def name_with_scale(class_: type["Scenario"], num: int, params_dict: dict) -> str:
  58. """Return the name of the Scenario including the scale.
  59. Used for running multiple instances of the same scenario via the
  60. parameterized python module.
  61. """
  62. return f"{class_.__name__}_scale_{params_dict['SCALE']}"
  63. def table_ten(self) -> TdAction:
  64. """Returns a Td() object that creates the 'ten' table"""
  65. return TdAction(
  66. """
  67. > CREATE TABLE ten (f1 INTEGER);
  68. > INSERT INTO ten VALUES (0)
  69. > INSERT INTO ten VALUES (1)
  70. > INSERT INTO ten VALUES (2)
  71. > INSERT INTO ten VALUES (3)
  72. > INSERT INTO ten VALUES (4)
  73. > INSERT INTO ten VALUES (5)
  74. > INSERT INTO ten VALUES (6)
  75. > INSERT INTO ten VALUES (7)
  76. > INSERT INTO ten VALUES (8)
  77. > INSERT INTO ten VALUES (9)
  78. """
  79. )
  80. def view_ten(self) -> TdAction:
  81. return TdAction(
  82. """
  83. > CREATE VIEW ten (f1) AS (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9));
  84. """
  85. )
  86. def unique_values(self) -> str:
  87. """Returns a string of the form 'a1.f1 + (a2.f1 * 10) + (a2.f1 * 100) ...'"""
  88. return " + ".join(
  89. f"(a{i+1}.f1 * {10**i})" for i in range(0, ceil(self.scale()))
  90. )
  91. def join(self) -> str:
  92. """Returns a string of the form 'ten AS a1 , ten AS a2 , ten AS a3 ...'"""
  93. return ", ".join(f"ten AS a{i+1}" for i in range(0, ceil(self.scale())))
  94. def keyschema(self) -> str:
  95. return (
  96. "\n"
  97. + '$ set keyschema={"type": "record", "name": "Key", "fields": [ { "name": "f1", "type": "long" } ] }'
  98. + "\n"
  99. )
  100. def schema(self) -> str:
  101. return (
  102. "\n"
  103. + '$ set schema={"type" : "record", "name" : "test", "fields": [ { "name": "f2", "type": "long" } ] }'
  104. + "\n"
  105. )
  106. # Used for benchmarks that are expected to run by default, e.g. in CI
  107. class Scenario(RootScenario):
  108. pass
  109. # Used for scenarios that need to be explicitly run from the command line using --root-scenario ScenarioBig
  110. class ScenarioBig(RootScenario):
  111. pass
  112. # Used for disabled scenarios
  113. class ScenarioDisabled(RootScenario):
  114. pass