|
17 | 17 | from __future__ import annotations
|
18 | 18 |
|
19 | 19 | import itertools
|
| 20 | +import uuid |
20 | 21 | from abc import ABC, abstractmethod
|
21 | 22 | from copy import copy
|
22 | 23 | from dataclasses import dataclass
|
@@ -498,6 +499,14 @@ def location(self) -> str:
|
498 | 499 | """Return the table's base location."""
|
499 | 500 | return self.metadata.location
|
500 | 501 |
|
| 502 | + def new_snapshot_id(self) -> int: |
| 503 | + """Generate a new snapshot-id that's not in use.""" |
| 504 | + snapshot_id = _generate_snapshot_id() |
| 505 | + while self.snapshot_by_id(snapshot_id) is not None: |
| 506 | + snapshot_id = _generate_snapshot_id() |
| 507 | + |
| 508 | + return snapshot_id |
| 509 | + |
501 | 510 | def current_snapshot(self) -> Optional[Snapshot]:
|
502 | 511 | """Get the current snapshot for this table, or None if there is no current snapshot."""
|
503 | 512 | if snapshot_id := self.metadata.current_snapshot_id:
|
@@ -1566,3 +1575,17 @@ def _add_and_move_fields(
|
1566 | 1575 | elif len(moves) > 0:
|
1567 | 1576 | return _move_fields(fields, moves)
|
1568 | 1577 | return None if len(adds) == 0 else tuple(*fields, *adds)
|
| 1578 | + |
| 1579 | + |
| 1580 | +def _generate_snapshot_id() -> int: |
| 1581 | + """Generate a new Snapshot ID from a UUID. |
| 1582 | +
|
| 1583 | + Returns: An 64 bit long |
| 1584 | + """ |
| 1585 | + rnd_uuid = uuid.uuid4() |
| 1586 | + snapshot_id = int.from_bytes( |
| 1587 | + bytes(lhs ^ rhs for lhs, rhs in zip(rnd_uuid.bytes[0:8], rnd_uuid.bytes[8:16])), byteorder='little', signed=True |
| 1588 | + ) |
| 1589 | + snapshot_id = snapshot_id if snapshot_id >= 0 else snapshot_id * -1 |
| 1590 | + |
| 1591 | + return snapshot_id |
0 commit comments