Initial commit: DeltaGlider - S3-compatible storage with 99.9% compression

- Drop-in replacement for AWS S3 CLI (cp, ls, rm, sync commands)
- Binary delta compression using xdelta3
- Hexagonal architecture with clean separation of concerns
- Achieves 99.9% compression for versioned files
- Full test suite with 100% passing tests
- Python 3.11+ support
This commit is contained in:
Simone Scarduzio
2025-09-22 22:21:48 +02:00
parent 7562064832
commit 7fbf84ed6c
21 changed files with 1939 additions and 71 deletions
+4 -2
View File
@@ -20,7 +20,8 @@ class XdeltaAdapter(DiffPort):
"-e", # encode
"-f", # force overwrite
"-9", # compression level
"-s", str(base), # source file
"-s",
str(base), # source file
str(target), # target file
str(out), # output delta
]
@@ -40,7 +41,8 @@ class XdeltaAdapter(DiffPort):
self.xdelta_path,
"-d", # decode
"-f", # force overwrite
"-s", str(base), # source file
"-s",
str(base), # source file
str(delta), # delta file
str(out), # output file
]
+1 -3
View File
@@ -18,9 +18,7 @@ class StdLoggerAdapter(LoggerPort):
if not self.logger.handlers:
handler = logging.StreamHandler(sys.stderr)
formatter = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
self.logger.addHandler(handler)
-1
View File
@@ -1,6 +1,5 @@
"""No-op metrics adapter."""
from ..ports.metrics import MetricsPort
+7 -3
View File
@@ -51,7 +51,12 @@ class S3StorageAdapter(StoragePort):
def list(self, prefix: str) -> Iterator[ObjectHead]:
"""List objects by prefix."""
bucket, prefix_key = self._parse_key(prefix)
# Handle bucket-only prefix (e.g., "bucket" or "bucket/")
if "/" not in prefix:
bucket = prefix
prefix_key = ""
else:
bucket, prefix_key = self._parse_key(prefix)
paginator = self.client.get_paginator("list_objects_v2")
pages = paginator.paginate(Bucket=bucket, Prefix=prefix_key)
@@ -69,7 +74,7 @@ class S3StorageAdapter(StoragePort):
try:
response = self.client.get_object(Bucket=bucket, Key=object_key)
return response["Body"]
return response["Body"] # type: ignore[return-value]
except ClientError as e:
if e.response["Error"]["Code"] == "NoSuchKey":
raise FileNotFoundError(f"Object not found: {key}") from e
@@ -133,4 +138,3 @@ class S3StorageAdapter(StoragePort):
"""Extract user metadata from S3 response."""
# S3 returns user metadata as-is (already lowercase)
return raw_metadata