cellfs
This commit is contained in:
@@ -9,6 +9,8 @@ var miniz = use('miniz')
|
||||
// Internal state
|
||||
var mounts = [] // Array of {source, type, handle, name}
|
||||
|
||||
var writepath = "."
|
||||
|
||||
// Helper to normalize paths
|
||||
function normalize_path(path) {
|
||||
if (!path) return ""
|
||||
@@ -102,40 +104,27 @@ function resolve(path, must_exist) {
|
||||
}
|
||||
|
||||
if (must_exist) {
|
||||
// throw new Error("File not found in any mount: " + path)
|
||||
return null
|
||||
throw new Error("File not found in any mount: " + path)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
// Mount a source
|
||||
function mount(source, name) {
|
||||
// Check if source exists
|
||||
var st = null
|
||||
try {
|
||||
st = fd.stat(source)
|
||||
} catch (e) {
|
||||
throw new Error("Mount source not found: " + source)
|
||||
}
|
||||
var st = fd.stat(source)
|
||||
|
||||
var mount_info = {
|
||||
source: source,
|
||||
name: name || null,
|
||||
type: 'fs',
|
||||
handle: null
|
||||
handle: null,
|
||||
zip_blob: null
|
||||
}
|
||||
|
||||
if (st.isDirectory) {
|
||||
mount_info.type = 'fs'
|
||||
} else if (st.isFile) {
|
||||
// Assume zip
|
||||
var zip_data = null
|
||||
// Always read as bytes for zip
|
||||
var f = fd.open(source, 'r')
|
||||
var s = fd.fstat(f)
|
||||
zip_data = fd.read(f, s.size)
|
||||
fd.close(f)
|
||||
var zip_data = fd.slurp(source)
|
||||
|
||||
var zip = miniz.read(zip_data)
|
||||
if (!zip || typeof zip.count != 'function') {
|
||||
@@ -144,6 +133,7 @@ function mount(source, name) {
|
||||
|
||||
mount_info.type = 'zip'
|
||||
mount_info.handle = zip
|
||||
mount_info.zip_blob = zip_data // keep blob alive for lifetime of mount
|
||||
} else {
|
||||
throw new Error("Unsupported mount source type: " + source)
|
||||
}
|
||||
@@ -177,37 +167,9 @@ function slurp(path) {
|
||||
}
|
||||
}
|
||||
|
||||
// Read file as bytes
|
||||
function slurpbytes(path) {
|
||||
var res = resolve(path, true)
|
||||
if (!res) throw new Error("File not found: " + path)
|
||||
|
||||
if (res.mount.type == 'zip') {
|
||||
return res.mount.handle.slurp(res.path)
|
||||
} else {
|
||||
var full_path = join_paths(res.mount.source, res.path)
|
||||
var f = fd.open(full_path, 'r')
|
||||
var s = fd.fstat(f)
|
||||
var data = fd.read(f, s.size)
|
||||
fd.close(f)
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
// Write file
|
||||
function slurpwrite(path, data) {
|
||||
if (!path.startsWith("@")) {
|
||||
throw new Error("slurpwrite requires a named mount (e.g. @name/file.txt)")
|
||||
}
|
||||
|
||||
var res = resolve(path, false)
|
||||
// For named mounts, resolve returns the mount even if file doesn't exist
|
||||
|
||||
if (res.mount.type == 'zip') {
|
||||
throw new Error("Cannot write to zip mount: @" + res.mount.name)
|
||||
}
|
||||
|
||||
var full_path = join_paths(res.mount.source, res.path)
|
||||
var full_path = writepath + "/" + path
|
||||
|
||||
var f = fd.open(full_path, 'w')
|
||||
fd.write(f, data)
|
||||
@@ -248,21 +210,31 @@ function stat(path) {
|
||||
|
||||
// Get search paths
|
||||
function searchpath() {
|
||||
var paths = []
|
||||
for (var mount of mounts) {
|
||||
paths.push(mount.source)
|
||||
}
|
||||
return paths
|
||||
return mounts.slice()
|
||||
}
|
||||
|
||||
// Initialize
|
||||
mount('.', 'cwd')
|
||||
// Mount a package using the shop system
|
||||
function mount_package(name) {
|
||||
if (name == null) {
|
||||
mount('.', null)
|
||||
return
|
||||
}
|
||||
|
||||
var shop = use('shop')
|
||||
var dir = shop.get_module_dir(name)
|
||||
|
||||
if (!dir) {
|
||||
throw new Error("Package not found: " + name)
|
||||
}
|
||||
|
||||
mount(dir, name)
|
||||
}
|
||||
|
||||
// Exports
|
||||
cellfs.mount = mount
|
||||
cellfs.mount_package = mount_package
|
||||
cellfs.unmount = unmount
|
||||
cellfs.slurp = slurp
|
||||
cellfs.slurpbytes = slurpbytes
|
||||
cellfs.slurpwrite = slurpwrite
|
||||
cellfs.exists = exists
|
||||
cellfs.stat = stat
|
||||
|
||||
@@ -6,6 +6,7 @@ var io = use('io')
|
||||
var time = use('time')
|
||||
var json = use('json')
|
||||
var blob = use('blob')
|
||||
var utf8 = use('utf8')
|
||||
|
||||
log.console("CellFS vs IO Performance Test")
|
||||
log.console("=================================")
|
||||
@@ -22,8 +23,7 @@ io.mount('.')
|
||||
|
||||
var io_paths = io.searchpath()
|
||||
log.console(io_paths)
|
||||
log.console(io_paths.length)
|
||||
log.console(typeof io_paths)
|
||||
|
||||
for (var i = 0; i < io_paths.length; i++) {
|
||||
var path = io_paths[i]
|
||||
try {
|
||||
@@ -53,7 +53,7 @@ log.console(`IO slurpbytes (100 iterations): ${io_time}ms`)
|
||||
// Test cellfs.slurpbytes
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 100; i++) {
|
||||
var content = cellfs.slurpbytes(test_file)
|
||||
var content = cellfs.slurp(test_file)
|
||||
}
|
||||
var cellfs_time = time.number() - start_time
|
||||
log.console(`CellFS slurpbytes (100 iterations): ${cellfs_time}ms`)
|
||||
@@ -110,28 +110,29 @@ var miniz = use('miniz')
|
||||
var zip_writer = miniz.write("test_archive.zip")
|
||||
// Use io.slurpbytes to get content as ArrayBuffer for miniz
|
||||
var content_bytes = io.slurpbytes(test_file)
|
||||
zip_writer.add_file("test.txt", content_bytes)
|
||||
zip_writer.add_file("test2.txt", content_bytes)
|
||||
zip_writer = null // Close it
|
||||
|
||||
// Mount the ZIP with io
|
||||
io.mount("test_archive.zip", "/test_zip")
|
||||
io.mount("test_archive.zip")
|
||||
|
||||
// Mount the ZIP with cellfs
|
||||
cellfs.mount("test_archive.zip", "/test_zip")
|
||||
cellfs.mount("test_archive.zip")
|
||||
|
||||
log.console("Testing ZIP file reading...")
|
||||
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 100; i++) {
|
||||
var content = io.slurp("test.txt")
|
||||
var content = io.slurp("test2.txt")
|
||||
}
|
||||
io_time = time.number() - start_time
|
||||
log.console(`IO ZIP read (100 iterations): ${io_time}ms`)
|
||||
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 100; i++) {
|
||||
var content = cellfs.slurp("test.txt")
|
||||
var content = cellfs.slurp("test2.txt")
|
||||
}
|
||||
|
||||
cellfs_time = time.number() - start_time
|
||||
log.console(`CellFS ZIP read (100 iterations): ${cellfs_time}ms`)
|
||||
|
||||
@@ -160,10 +161,9 @@ for (var i = 0; i < 10; i++) {
|
||||
io_time = time.number() - start_time
|
||||
log.console(`IO large file read (10 iterations): ${io_time}ms`)
|
||||
|
||||
// Test cellfs.slurpbytes
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var large_content = cellfs.slurpbytes(large_file)
|
||||
var large_content = cellfs.slurp(large_file)
|
||||
}
|
||||
cellfs_time = time.number() - start_time
|
||||
log.console(`CellFS large file read (10 iterations): ${cellfs_time}ms`)
|
||||
|
||||
51
tests/miniz.ce
Normal file
51
tests/miniz.ce
Normal file
@@ -0,0 +1,51 @@
|
||||
var fd = use("fd")
|
||||
var miniz = use("miniz")
|
||||
var utf8 = use("utf8")
|
||||
|
||||
var ZIP_PATH = "miniz_test.zip"
|
||||
var SOURCE_PATH = "miniz_source.txt"
|
||||
var ENTRY_PATH = "sample/hello.txt"
|
||||
var PAYLOAD = "Miniz integration test payload."
|
||||
|
||||
function write_text_file(path, text) {
|
||||
var handle = fd.open(path, "w")
|
||||
fd.write(handle, text)
|
||||
fd.close(handle)
|
||||
}
|
||||
|
||||
function main() {
|
||||
log.console("[miniz] creating source file via fd module...")
|
||||
write_text_file(SOURCE_PATH, PAYLOAD)
|
||||
|
||||
log.console("[miniz] creating zip via fd-backed filesystem...")
|
||||
var source_blob = fd.slurp(SOURCE_PATH)
|
||||
var writer = miniz.write(ZIP_PATH)
|
||||
writer.add_file(ENTRY_PATH, source_blob)
|
||||
writer = null
|
||||
|
||||
log.console("[miniz] zip written; reading back through fd module")
|
||||
var zip_blob = fd.slurp(ZIP_PATH)
|
||||
var reader = miniz.read(zip_blob)
|
||||
|
||||
if (!reader.exists(ENTRY_PATH))
|
||||
throw new Error("miniz test: entry missing in archive")
|
||||
|
||||
var extracted_blob = reader.slurp(ENTRY_PATH)
|
||||
var extracted_text = utf8.decode(extracted_blob)
|
||||
log.console(reader.list())
|
||||
log.console(extracted_text);
|
||||
|
||||
if (extracted_text != PAYLOAD)
|
||||
throw new Error("miniz test: extracted text mismatch")
|
||||
|
||||
var listed = reader.list()
|
||||
if (listed.length != reader.count())
|
||||
throw new Error("miniz test: list/count mismatch")
|
||||
if (listed.length != 1 || listed[0] != ENTRY_PATH)
|
||||
throw new Error("miniz test: unexpected entries in archive")
|
||||
|
||||
log.console(`miniz read success: ${listed[0]} => ${extracted_text}`)
|
||||
$_.stop()
|
||||
}
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user