~mil/mepo

16505f91ca5b914dedb9a921d720193863527e68 — Miles Alan 2 years ago bc799eb cache-dir-hierarchy
Implement hierarchy / subfolders for cachedir source/z/z_x_y.png
1 files changed, 39 insertions(+), 21 deletions(-)

M src/TileCache.zig
M src/TileCache.zig => src/TileCache.zig +39 -21
@@ 49,7 49,7 @@ thread_download: ?*sdl.SDL_Thread = null,
thread_queuebbox: ?*sdl.SDL_Thread = null,
bbox_queue: ?DownloadBBoxRequest = null,
byte_counter: u64 = 0,
cache_dir: ?std.fs.Dir,
cache_dir: ?[:0]const u8,
curl_multi: *curl.CURLM,
max_n_transfers: usize = 20,
queue_lifo: datastructure.QueueHashMap(types.XYZ, bool),


@@ 69,15 69,20 @@ pub fn tile_retrieve(tile_cache: *@This(), coords: types.XYZ) !TileData {
    } else if (tile_cache.transfer_map.get(coords)) |transfer| {
        return TileData{ .transfer_datum = transfer.* };
    } else if (tile_cache.cache_dir) |cache_dir| load_from_fs: {
        const png = try png_path(tile_cache.allocator, tile_cache.source_url.?, coords);
        const png = try tile_cache.png_path(tile_cache.source_url.?, coords);
        defer tile_cache.allocator.free(png);
        file_cached_png_opt = cache_dir.readFileAlloc(tile_cache.allocator, png, 500000) catch null;
        if (file_cached_png_opt) |file_cached_png| {
            defer tile_cache.allocator.free(file_cached_png);
            const text = tile_cache.load_data_to_texture(coords, file_cached_png) catch {
                break :load_from_fs;
            };
            return TileData{ .texture = text };
        if (std.fs.openFileAbsolute(png, .{ .write = true, .read = true })) |file| {
            defer file.close();
            file_cached_png_opt = file.readToEndAlloc(tile_cache.allocator, 500000) catch null;
            if (file_cached_png_opt) |file_cached_png| {
                defer tile_cache.allocator.free(file_cached_png);
                const text = tile_cache.load_data_to_texture(coords, file_cached_png) catch {
                    break :load_from_fs;
                };
                return TileData{ .texture = text };
            }
        } else |err| {
            break :load_from_fs;
        }
    }



@@ 96,9 101,9 @@ pub fn tile_retrieve(tile_cache: *@This(), coords: types.XYZ) !TileData {
/// present.
fn tile_queue_no_surface_load(tile_cache: *@This(), coords: types.XYZ) !bool {
    if (tile_cache.cache_dir) |cache_dir| check_exists: {
        const png = try png_path(tile_cache.allocator, tile_cache.source_url.?, coords);
        const png = try tile_cache.png_path(tile_cache.source_url.?, coords);
        defer tile_cache.allocator.free(png);
        cache_dir.access(png, .{}) catch break :check_exists;
        std.fs.accessAbsolute(png, .{}) catch break :check_exists;
        return false;
    }



@@ 271,8 276,14 @@ fn transfer_complete(tile_cache: *@This(), msg: *curl.CURLMsg) !void {

                if (tile_cache.cache_dir) |cache_dir| {
                    // Save to FS
                    const path = try png_path(tile_cache.allocator, tile_cache.source_url.?, coords);
                    try cache_dir.writeFile(path, datum_array);
                    const path = try tile_cache.png_path(tile_cache.source_url.?, coords);
                    defer tile_cache.allocator.free(path);
                    var dir = try std.fs.openDirAbsolute("/", .{});
                    defer dir.close();
                    try dir.makePath(std.fs.path.dirname(path).?);
                    const file = try std.fs.createFileAbsolute(path, .{});
                    defer file.close();
                    _ = try file.write(datum_array);
                }
                if (tile_cache.transfer_map.get(coords).?.load_to_texture) {
                    // Load to surface


@@ 334,13 345,21 @@ fn tile_write_curl_callback(
    return nmemb * size;
}

fn png_path(allocator: *std.mem.Allocator, source: []const u8, coords: types.XYZ) ![]u8 {
fn png_path(tile_cache: *@This(), source: []const u8, coords: types.XYZ) ![]u8 {
    var source_hash: [32:0]u8 = undefined;
    std.crypto.hash.sha2.Sha256.hash(source, &source_hash, .{});
    // E.g. cache_dir/source/z/z_x_y.png
    return try std.fmt.allocPrint(
        allocator,
        "{s}_{d}_{d}_{d}.png",
        .{ std.fmt.fmtSliceHexLower(source_hash[0..8]), coords.z, coords.x, coords.y },
        tile_cache.allocator,
        "{s}/{s}/{d}/{d}_{d}_{d}.png",
        .{
            tile_cache.cache_dir,
            std.fmt.fmtSliceHexLower(source_hash[0..8]),
            coords.z,
            coords.z,
            coords.x,
            coords.y,
        },
    );
}



@@ 448,10 467,9 @@ pub fn set_network(tile_cache: *@This(), enable: bool) void {
}

pub fn set_cache_dir(tile_cache: *@This(), path: [:0]const u8) !void {
    const expanded_path = try utilfile.wordexp_filepath(tile_cache.allocator, path);
    defer tile_cache.allocator.free(expanded_path);
    try std.fs.cwd().makePath(expanded_path);
    tile_cache.cache_dir = try std.fs.cwd().openDir(expanded_path, .{ .iterate = true });
    if (tile_cache.cache_dir != null) tile_cache.allocator.free(tile_cache.cache_dir.?);
    tile_cache.cache_dir = try utilfile.wordexp_filepath(tile_cache.allocator, path);
    try std.fs.cwd().makePath(tile_cache.cache_dir.?);
}

/// Sets the cache URL, making copy of str