From c9de47d664125871e29bbf094ef86226b1835945 Mon Sep 17 00:00:00 2001 From: sw1py Date: Fri, 25 Sep 2026 23:51:25 +0300 Subject: [PATCH] Solve task 1 --- src/part1/constants.py | 17 ++++++------- src/part1/snowflake.py | 57 +++++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/src/part1/constants.py b/src/part1/constants.py index 9abfbba2..4705a214 100644 --- a/src/part1/constants.py +++ b/src/part1/constants.py @@ -16,23 +16,22 @@ # TODO: замените заглушки (0) на корректные значения, см. TASK.md. -# Все константы, зависящие от ёмкостей *_BITS, должны вычисляться из них. # Twitter's original Snowflake epoch: 2010-11-04 01:42:54.657 UTC. -EPOCH_MS_DEFAULT: Final[int] = 0 +EPOCH_MS_DEFAULT: Final[int] = 1288834974657 # Node identifier used when the caller does not supply one. -NODE_ID_DEFAULT: Final[int] = 0 +NODE_ID_DEFAULT: Final[int] = 1 # Width of each field, in bits. -TIMESTAMP_BITS: Final[int] = 0 -NODE_ID_BITS: Final[int] = 0 -SEQUENCE_ID_BITS: Final[int] = 0 +TIMESTAMP_BITS: Final[int] = 41 +NODE_ID_BITS: Final[int] = 10 +SEQUENCE_ID_BITS: Final[int] = 12 # Largest value each field can hold. -TIMESTAMP_MS_MAX: Final[int] = 0 -NODE_ID_MAX: Final[int] = 0 -SEQUENCE_ID_MAX: Final[int] = 0 +TIMESTAMP_MS_MAX: Final[int] = 2 ** TIMESTAMP_BITS - 1 +NODE_ID_MAX: Final[int] = 2 ** NODE_ID_BITS - 1 +SEQUENCE_ID_MAX: Final[int] = 2 ** SEQUENCE_ID_BITS - 1 # Здесь можно добавить собственные вспомогательные константы # (например, сдвиги полей при сборке идентификатора). diff --git a/src/part1/snowflake.py b/src/part1/snowflake.py index d3abf050..24cc4c63 100644 --- a/src/part1/snowflake.py +++ b/src/part1/snowflake.py @@ -21,37 +21,27 @@ NODE_ID_MAX, SEQUENCE_ID_MAX, TIMESTAMP_MS_MAX, + NODE_ID_BITS, + SEQUENCE_ID_BITS ) def read_current_millis(epoch_ms: int) -> int: - """Read the number of milliseconds elapsed since the custom epoch. - Args: - epoch_ms: The custom epoch expressed as Unix milliseconds. + user_time = int(time.time() * 1000) + + differnse_time = user_time - epoch_ms - Returns: - The count of whole milliseconds between ``epoch_ms`` and now. May be - negative if ``epoch_ms`` lies in the future. - """ - # TODO: реализуйте функцию - return 0 + return differnse_time def decode_timestamp_ms(snowflake_id: int, epoch_ms: int = EPOCH_MS_DEFAULT) -> int: - """Read the timestamp field out of a Snowflake identifier. - Args: - snowflake_id: An identifier produced against the same epoch. - epoch_ms: The epoch the identifier was generated against. Defaults to - the original Twitter epoch (2010-11-04 01:42:54.657 UTC). + user_mc = snowflake_id >> (NODE_ID_BITS + SEQUENCE_ID_BITS) - Returns: - The absolute Unix time in milliseconds at which the identifier was - generated. - """ - # TODO: реализуйте функцию - return 0 + absolut_time = user_mc + epoch_ms + + return absolut_time def decode_node_id(snowflake_id: int) -> int: @@ -64,8 +54,8 @@ def decode_node_id(snowflake_id: int) -> int: The node identifier packed into ``snowflake_id``, in the range ``[0, NODE_ID_MAX]``. """ - # TODO: реализуйте функцию - return 0 + identifier_id = (snowflake_id >> SEQUENCE_ID_BITS) & NODE_ID_MAX + return identifier_id def decode_sequence_id(snowflake_id: int) -> int: @@ -78,8 +68,8 @@ def decode_sequence_id(snowflake_id: int) -> int: The per-millisecond sequence counter packed into ``snowflake_id``, in the range ``[0, SEQUENCE_ID_MAX]``. """ - # TODO: реализуйте функцию - return 0 + sequence_id = snowflake_id & SEQUENCE_ID_MAX + return sequence_id def generate_snowflake_id( @@ -110,5 +100,20 @@ def generate_snowflake_id( timestamp field (roughly 69 years after ``epoch_ms``). In each of those cases an explanatory message is printed to stdout first. """ - # TODO: реализуйте функцию - return 0 + if node_id < 0 or node_id > NODE_ID_MAX: + print(f"node_id must be in [0, {NODE_ID_MAX}], got {node_id}") + return None + if sequence_id < 0 or sequence_id > SEQUENCE_ID_MAX: + print(f"sequence_id must be in [0, {SEQUENCE_ID_MAX}], got {sequence_id}") + return None + elapsed_ms = read_current_millis(epoch_ms) + if elapsed_ms > TIMESTAMP_MS_MAX: + print(f"timestamp overflows: {elapsed_ms} > {TIMESTAMP_MS_MAX}") + return None + snowflake_id = ( + (elapsed_ms << (NODE_ID_BITS + SEQUENCE_ID_BITS)) + | (node_id << SEQUENCE_ID_BITS) + | sequence_id + ) + return snowflake_id +