Compression
How Hyperbasis compresses ARWorldMap data.
Overview
ARWorldMap data is typically 5-50 MB. Hyperbasis uses zlib compression to reduce storage size and upload times.
Compression API
public enum HBCompression {
public static func compress(_ data: Data, level: HBCompressionLevel) throws -> Data
public static func decompress(_ data: Data) throws -> Data
}Compression Levels
public enum HBCompressionLevel {
case none // No compression
case balanced // zlib default (~40% reduction)
}None
- •No compression applied
- •Fastest save/load times
- •Largest file sizes
- •Best for development/debugging
Balanced
- •zlib default compression
- •~40% size reduction on typical ARWorldMap data
- •Slight CPU overhead
- •Recommended for production
Implementation Details
Hyperbasis uses Apple's Compression framework with the zlib algorithm:
import Compression
// Compression
let compressedSize = compression_encode_buffer(
destinationBuffer,
destinationCapacity,
sourceBuffer,
sourceSize,
nil,
COMPRESSION_ZLIB
)
// Decompression
let decompressedSize = compression_decode_buffer(
destinationBuffer,
destinationCapacity,
sourceBuffer,
sourceSize,
nil,
COMPRESSION_ZLIB
)Size Comparisons
| Environment | Uncompressed | Compressed | Reduction |
|---|---|---|---|
| Small room | 8 MB | 4.8 MB | 40% |
| Medium room | 18 MB | 10.8 MB | 40% |
| Large space | 45 MB | 27 MB | 40% |
ARWorldMap data compresses well because it contains redundant feature point data. Compression ratios are consistent across different environment sizes.
Configuration
Set compression level in HBStorageConfig:
// No compression (development)
let devConfig = HBStorageConfig(
backend: .localOnly,
syncStrategy: .manual,
compression: .none
)
// Balanced compression (production)
let prodConfig = HBStorageConfig(
backend: .supabase(url: url, anonKey: key),
syncStrategy: .onSave,
compression: .balanced
)When to Use Each Level
Use .none when:
- •Debugging world map issues
- •CPU is constrained
- •Storage space is unlimited
- •Development/testing
Use .balanced when:
- •Production deployment
- •Cloud sync is enabled
- •Storage costs matter
- •Normal usage
Error Handling
public enum HBStorageError: LocalizedError {
case compressionFailed(underlying: Error)
case decompressionFailed(underlying: Error)
}do {
let space = try await storage.loadSpace(id: spaceId)
} catch HBStorageError.decompressionFailed(let error) {
// Handle corrupted or incompatible compression
print("Failed to decompress world map: \(error)")
}Compression Flag
Stored data includes a flag indicating whether compression was used:
{
"id": "space-uuid",
"worldMapData": "base64-data...",
"isCompressed": true
}This ensures data compressed with one setting can be read regardless of current configuration.
Performance Considerations
Compression Time
| Size | Compression Time |
|---|---|
| 10 MB | ~50ms |
| 25 MB | ~120ms |
| 50 MB | ~250ms |
Decompression Time
Decompression is typically 2-3x faster than compression.
Memory Usage
Compression requires temporary buffers. For a 50 MB world map:
- •~50 MB source buffer
- •~50 MB destination buffer (pre-allocated)
- •Total: ~100 MB peak memory during compression
On memory-constrained devices, consider saving spaces when the app has available memory, not during memory pressure situations.
Next Steps
- •Configuration - Set compression level
- •HBStorage - Storage operations