~mil/mepo

906ea7a7288a30b3c9c08ec119855374b28a2e0f — Miles Alan 2 years ago 056ff42 linkedlist-backed-queuemap
Fix syntax errors allowing to actually compile
2 files changed, 27 insertions(+), 21 deletions(-)

M src/TileCache.zig
M src/datastructure/datastructure.zig
M src/TileCache.zig => src/TileCache.zig +17 -12
@@ 82,8 82,11 @@ pub fn download_loop(tile_cache: *@This(), graphical_mode: bool) !void {

        // 2. Transfer from LIFO into transfers
        while (tile_cache.queue_lifo.count() > 0 and tile_cache.transfer_map.count() < tile_cache.max_n_transfers) {
            var coords = tile_cache.queue_lifo.pop();
            try tile_cache.curl_add_to_multi_and_register_transfer(coords.key, coords.value);
            if (tile_cache.queue_lifo.pop(.Head)) |coords| {
                try tile_cache.curl_add_to_multi_and_register_transfer(coords.key, coords.metadata);
            } else {
                break;
            }
        }

        // 3. Print status message if non graphical


@@ 103,7 106,8 @@ pub fn download_loop(tile_cache: *@This(), graphical_mode: bool) !void {

    // Purge out in-progress transfers on thread termination
    while (tile_cache.transfer_map.count() > 0) {
        tile_cache.download_loop_transfer_cleanup(tile_cache.transfer_map.values()[0].client) catch |e| {
        var it = tile_cache.transfer_map.iterator();
        tile_cache.download_loop_transfer_cleanup(it.next().?.value_ptr.*.data.metadata.client) catch |e| {
            utildbg.log("Failed to cleanup in-progress transfer on download thread termination: {}\n", .{e});
        };
    }


@@ 120,7 124,8 @@ pub fn set_cache_url(tile_cache: *@This(), url: [:0]const u8) !void {
    defer utilsdl.sdl_push_resize_event();

    // Empty Texture map & queue
    for (tile_cache.texture_map.values()) |t| sdl.SDL_DestroyTexture(t);
    var it = tile_cache.texture_map.iterator();
    while (it.next()) |t| sdl.SDL_DestroyTexture(t.value_ptr.*.data.metadata);
    tile_cache.texture_map.clearAndFree();
    tile_cache.queue_lifo.clearAndFree();



@@ 211,9 216,9 @@ pub fn tile_retrieve(tile_cache: *@This(), coords: types.XYZ) !TileData {
    if (tile_cache.thread_download == null) {
        return TileData{ .error_type = .Offline };
    } else {
        try tile_cache.queue_lifo.put(coords, true);
        try tile_cache.queue_lifo.put(.Head, coords, true);
        return TileData{
            .queued_position = @intCast(u32, if (tile_cache.queue_lifo.getIndex(coords)) |index| index else 0),
            .queued_position = 99999,
        };
    }
}


@@ 253,7 258,7 @@ pub fn tile_queue_no_surface_load_bbox(tile_cache: *@This(), dl_req: DownloadBBo
                    n_cached += 1;
                } else {
                    n_queued += 1;
                    try tile_cache.queue_lifo.put(coords, false);
                    try tile_cache.queue_lifo.put(.Tail, coords, false);
                }
            }
        }


@@ 281,7 286,7 @@ fn curl_add_to_multi_and_register_transfer(tile_cache: *@This(), coords: types.X
        dat.load_to_texture = load_to_texture;
        break :datum dat;
    };
    try tile_cache.transfer_map.put(coords, transfer_datum);
    try tile_cache.transfer_map.put(.Head, coords, transfer_datum);

    var tile_url = url: {
        var url = try tile_cache.allocator.alloc(u8, tile_cache.source_url.?.len + (3 * 10));


@@ 347,8 352,8 @@ fn curl_errorcheck(response: curl.CURLMcode) !void {
fn curl_client_to_coords(tile_cache: *@This(), client: ?*curl.CURL) ?types.XYZ {
    var it = tile_cache.transfer_map.iterator();
    while (it.next()) |kv| {
        if (kv.value_ptr.*.client == client) {
            return kv.value_ptr.*.coords;
        if (kv.value_ptr.*.data.metadata.client == client) {
            return kv.value_ptr.*.data.metadata.coords;
        }
    }
    return null;


@@ 428,7 433,7 @@ fn download_loop_transfer_cleanup(tile_cache: *@This(), client: ?*curl.CURL) !vo
        const transfer_datum = tile_cache.transfer_map.get(coords).?;
        const datum_array = transfer_datum.data_arraylist.items;
        tile_cache.transfer_map.get(coords).?.data_arraylist.deinit();
        _ = tile_cache.transfer_map.swapRemove(coords);
        _ = tile_cache.transfer_map.remove(coords);
        tile_cache.allocator.destroy(transfer_datum);

        try curl_errorcheck(curl.curl_multi_remove_handle(tile_cache.curl_multi, client));


@@ 446,7 451,7 @@ fn load_data_to_texture(tile_cache: *@This(), coords: types.XYZ, data: []u8) !*s
    // TODO: should there be some limit on size of texture map cache?
    //       currently memory will just accumulate there ad-infinitum
    //defer sdl.SDL_DestroyTexture(texture);
    try tile_cache.texture_map.put(coords, texture);
    try tile_cache.texture_map.put(.Tail, coords, texture);
    return tile_cache.texture_map.get(coords).?;
}


M src/datastructure/datastructure.zig => src/datastructure/datastructure.zig +10 -9
@@ 36,6 36,7 @@ pub fn QueueHashMap(comptime key_type: type, comptime metadata_type: type) type 
            if (self.array_hash_map.get(key)) |got| {
                return got.data.metadata;
            }
            return null;
        }

        pub fn count(self: *@This()) usize {


@@ 45,20 46,20 @@ pub fn QueueHashMap(comptime key_type: type, comptime metadata_type: type) type 
            return self.array_hash_map.count();
        }

        pub fn pop(self: *@This(), position: Position) struct { key: key_type, value: metadata_type } {
        pub fn pop(self: *@This(), position: Position) ?NodeDatum {
            const lock = self.mutex.acquire();
            defer lock.release();

            const popped_node = if (position == .Head) self.ll.popFirst() else self.ll.pop();
            if (popped_node) {
                defer self.allocator.free(popped_node);
                return .{
            const popped_node_opt = if (position == .Head) self.ll.popFirst() else self.ll.pop();
            if (popped_node_opt) |popped_node| {
                defer self.allocator.destroy(popped_node);
                return NodeDatum{
                    .key = popped_node.data.key,
                    .value = popped_node.data.metadata_value,
                    .metadata = popped_node.data.metadata,
                };
            }

            return .{ .key = popped.key, .value = popped.value };
            return null;
        }

        pub fn remove(self: *@This(), key: key_type) void {


@@ 67,11 68,11 @@ pub fn QueueHashMap(comptime key_type: type, comptime metadata_type: type) type 

            if (self.array_hash_map.get(key)) |got| {
                self.ll.remove(got);
                self.array_hash_map.swapRemove(key);
                _ = self.array_hash_map.swapRemove(key);
            }
        }

        pub fn iterator(self: *@This()) std.array_hash_map.AutoArrayHashMap(key_type, metadata_type).Iterator {
        pub fn iterator(self: *@This()) std.array_hash_map.AutoArrayHashMap(key_type, *NodeQueue.Node).Iterator {
            const lock = self.mutex.acquire();
            defer lock.release();