signoz/tests/integration/fixtures/fingerprint.py

55 lines
1.6 KiB
Python
Raw Permalink Normal View History

from abc import ABC
from typing import Any
class LogsOrTracesFingerprint(ABC):
attributes: dict[str, Any]
def __init__(self, attributes: dict[str, Any]) -> None:
self.attributes = attributes
def calculate(self) -> str:
parts = []
for attr in self.attributes:
parts.append(f"{attr}={self.attributes[attr]}")
fhash = LogsOrTracesFingerprint.hash(self.attributes)
parts.append(f"hash={fhash}")
return ";".join(parts)
@staticmethod
def hash(attributes: dict[str, Any]) -> int:
# FNV-1a constants
offset64 = 14695981039346656037
prime64 = 1099511628211
separator_byte = 255
if not attributes:
return offset64
def hash_add(h: int, s: str) -> int:
"""Add a string to a fnv64a hash value, returning the updated hash."""
for char in s:
h ^= ord(char)
h = (h * prime64) & 0xFFFFFFFFFFFFFFFF # Keep 64-bit
return h
def hash_add_byte(h: int, b: int) -> int:
"""Add a byte to a fnv64a hash value, returning the updated hash."""
h ^= b
h = (h * prime64) & 0xFFFFFFFFFFFFFFFF # Keep 64-bit
return h
# Sort keys to ensure consistent hash
keys = sorted(attributes.keys())
sum_hash = offset64
for key in keys:
sum_hash = hash_add(sum_hash, key)
sum_hash = hash_add_byte(sum_hash, separator_byte)
sum_hash = hash_add(sum_hash, str(attributes[key]))
sum_hash = hash_add_byte(sum_hash, separator_byte)
return sum_hash