This commit is contained in:
2025-09-13 18:38:31 +02:00
parent aa38f44258
commit 820ef4bc49
9 changed files with 86 additions and 237 deletions

19
lib/hero/herofs/fs.v Normal file
View File

@@ -0,0 +1,19 @@
module herofs
import time
import crypto.blake3
import json
// Fs represents a filesystem, is the top level container for files and directories and symlinks, blobs are used over filesystems
@[heap]
pub struct Fs {
pub mut:
name string
group_id u32 // Associated group for permissions
root_dir_id u32 // ID of root directory
quota_bytes u64 // Storage quota in bytes
used_bytes u64 // Current usage in bytes
}
// We only keep the root directory ID here, other directories can be found by querying parent_id in FsDir

View File

@@ -1,4 +1,4 @@
module heromodels
module herofs
import time
import crypto.blake3
@@ -7,17 +7,17 @@ import crypto.blake3
@[heap]
pub struct FsBlob {
pub mut:
id string // blake192 hash of content
hash string // blake192 hash of content
data []u8 // Binary data (max 1MB)
size_bytes int // Size in bytes
created_at i64
mime_type string
encoding string // e.g., "gzip", "none"
mime_type string //TODO: is there not more formal way how to store mime types? enum? or list is too long?
encoding string //TODO: make enum
}
pub fn (mut b FsBlob) calculate_id() {
pub fn (mut b FsBlob) calculate_hash() {
hash := blake3.sum256(b.data)
b.id = hash.hex()[..48] // blake192 = first 192 bits = 48 hex chars
b.hash = hash.hex()[..48] // blake192 = first 192 bits = 48 hex chars
}
pub fn new_fs_blob(data []u8) !FsBlob {
@@ -39,3 +39,5 @@ pub fn (b FsBlob) verify_integrity() bool {
hash := blake3.sum256(b.data)
return hash.hex()[..48] == b.id
}
//TODO: we will need other hset so we can go back from hash to id (which is u32)

16
lib/hero/herofs/fs_dir.v Normal file
View File

@@ -0,0 +1,16 @@
module herofs
import time
import crypto.blake3
import json
// FsDir represents a directory in a filesystem
@[heap]
pub struct FsDir {
pub mut:
name string
fs_id u32 // Associated filesystem
parent_id u32 // Parent directory ID (empty for root)
}
//we only keep the parents, not the children, as children can be found by doing a query on parent_id, we will need some smart hsets to make this fast enough and efficient

21
lib/hero/herofs/fs_file.v Normal file
View File

@@ -0,0 +1,21 @@
module herofs
import time
import crypto.blake3
import json
// FsFile represents a file in a filesystem
@[heap]
pub struct FsFile {
pub mut:
name string
fs_id string // Associated filesystem
directories []u32 // Directory IDs where this file exists, means file can be part of multiple directories (like hard links in Linux)
blobs []u32 // Blake192 IDs of file content blobs (we reference them with u32 IDs for efficiency)
size_bytes u64
mime_type string // e.g., "image/png"
checksum string // e.g., SHA256 checksum of the file
accessed_at i64
metadata map[string]string // Custom metadata
}

View File

@@ -0,0 +1,22 @@
module herofs
import time
import crypto.blake3
import json
// FsSymlink represents a symbolic link in a filesystem
@[heap]
pub struct FsSymlink {
pub mut:
name string
fs_id u32 // Associated filesystem
parent_id u32 // Parent directory ID
target_id u32 // ID of target file or directory
target_type SymlinkTargetType
}
pub enum SymlinkTargetType {
file
directory
}

View File

@@ -1,52 +0,0 @@
module heromodels
import time
import crypto.blake3
import json
// Fs represents a filesystem namespace
@[heap]
pub struct Fs {
pub mut:
id string // blake192 hash
name string
description string
group_id string // Associated group for permissions
root_dir_id string // ID of root directory
created_at i64
updated_at i64
quota_bytes i64 // Storage quota in bytes
used_bytes i64 // Current usage in bytes
tags []string
}
pub fn (mut f Fs) calculate_id() {
content := json.encode(FsContent{
name: f.name
description: f.description
group_id: f.group_id
quota_bytes: f.quota_bytes
tags: f.tags
})
hash := blake3.sum256(content.bytes())
f.id = hash.hex()[..48]
}
struct FsContent {
name string
description string
group_id string
quota_bytes i64
tags []string
}
pub fn new_fs(name string, group_id string) Fs {
mut fs := Fs{
name: name
group_id: group_id
created_at: time.now().unix()
updated_at: time.now().unix()
}
fs.calculate_id()
return fs
}

View File

@@ -1,53 +0,0 @@
module heromodels
import time
import crypto.blake3
import json
// FsDir represents a directory in a filesystem
@[heap]
pub struct FsDir {
pub mut:
id string // blake192 hash
name string
fs_id string // Associated filesystem
parent_id string // Parent directory ID (empty for root)
group_id string // Associated group for permissions
children []string // Child directory and file IDs
created_at i64
updated_at i64
tags []string
}
pub fn (mut d FsDir) calculate_id() {
content := json.encode(DirContent{
name: d.name
fs_id: d.fs_id
parent_id: d.parent_id
group_id: d.group_id
tags: d.tags
})
hash := blake3.sum256(content.bytes())
d.id = hash.hex()[..48]
}
struct DirContent {
name string
fs_id string
parent_id string
group_id string
tags []string
}
pub fn new_fs_dir(name string, fs_id string, parent_id string, group_id string) FsDir {
mut dir := FsDir{
name: name
fs_id: fs_id
parent_id: parent_id
group_id: group_id
created_at: time.now().unix()
updated_at: time.now().unix()
}
dir.calculate_id()
return dir
}

View File

@@ -1,65 +0,0 @@
module heromodels
import time
import crypto.blake3
import json
// FsFile represents a file in a filesystem
@[heap]
pub struct FsFile {
pub mut:
id string // blake192 hash
name string
fs_id string // Associated filesystem
directories []string // Directory IDs where this file exists
blobs []string // Blake192 IDs of file content blobs
size_bytes i64 // Total file size
mime_type string
checksum string // Overall file checksum
created_at i64
updated_at i64
accessed_at i64
tags []string
metadata map[string]string // Custom metadata
}
pub fn (mut f FsFile) calculate_id() {
content := json.encode(FileContent{
name: f.name
fs_id: f.fs_id
directories: f.directories
blobs: f.blobs
size_bytes: f.size_bytes
mime_type: f.mime_type
checksum: f.checksum
tags: f.tags
metadata: f.metadata
})
hash := blake3.sum256(content.bytes())
f.id = hash.hex()[..48]
}
struct FileContent {
name string
fs_id string
directories []string
blobs []string
size_bytes i64
mime_type string
checksum string
tags []string
metadata map[string]string
}
pub fn new_fs_file(name string, fs_id string, directories []string) FsFile {
mut file := FsFile{
name: name
fs_id: fs_id
directories: directories
created_at: time.now().unix()
updated_at: time.now().unix()
accessed_at: time.now().unix()
}
file.calculate_id()
return file
}

View File

@@ -1,61 +0,0 @@
module heromodels
import time
import crypto.blake3
import json
// FsSymlink represents a symbolic link in a filesystem
@[heap]
pub struct FsSymlink {
pub mut:
id string // blake192 hash
name string
fs_id string // Associated filesystem
parent_id string // Parent directory ID
target_id string // ID of target file or directory
target_type SymlinkTargetType
created_at i64
updated_at i64
tags []string
}
pub enum SymlinkTargetType {
file
directory
}
pub fn (mut s FsSymlink) calculate_id() {
content := json.encode(SymlinkContent{
name: s.name
fs_id: s.fs_id
parent_id: s.parent_id
target_id: s.target_id
target_type: s.target_type
tags: s.tags
})
hash := blake3.sum256(content.bytes())
s.id = hash.hex()[..48]
}
struct SymlinkContent {
name string
fs_id string
parent_id string
target_id string
target_type SymlinkTargetType
tags []string
}
pub fn new_fs_symlink(name string, fs_id string, parent_id string, target_id string, target_type SymlinkTargetType) FsSymlink {
mut symlink := FsSymlink{
name: name
fs_id: fs_id
parent_id: parent_id
target_id: target_id
target_type: target_type
created_at: time.now().unix()
updated_at: time.now().unix()
}
symlink.calculate_id()
return symlink
}