Skip to content

Instantly share code, notes, and snippets.

@BruceChen7
Last active August 1, 2022 15:29
Show Gist options
  • Save BruceChen7/a61ca9dab2385de822c8bac26baaaa3d to your computer and use it in GitHub Desktop.
Save BruceChen7/a61ca9dab2385de822c8bac26baaaa3d to your computer and use it in GitHub Desktop.
#ziglang#type#zig#async
// 固定数组,类型体操
// [Zig lang 初体验 -- 『大道至简』的 comptime - 纯纯的 Blog](https://blog.zhuangty.com/zig-lang-comptime/)
const std = @import("std");
const ArrayList = std.ArrayList;
const DynamicBitSet = std.bit_set.DynamicBitSet;
fn FixedArray(comptime T: type) type {
return struct {
const Self = @This();
data: ArrayList(T),
validity: DynamicBitSet,
pub const Ref = T;
pub fn deinit(self: *Self) void {
self.data.deinit();
self.validity.deinit();
}
pub fn value(self: *const Self, idx: usize) ?Self.Ref {
if (self.validity.isSet(idx)) {
return self.data.items[idx];
} else {
return null;
}
}
pub fn len(self: *const Self) usize {
return self.data.len();
}
};
}
// 类型可以做逻辑
// ...
const sizeLarge = (@sizeOf(T) > 8);
pub const Ref = if (sizeLarge > 8) *T else T;
// ...
pub fn value(self: *const Self, idx: usize) ?Self.Ref {
if (self.validity.isSet(idx)) {
if (sizeLarge) {
return &self.data.items[idx];
} else {
return self.data.items[idx];
}
} else {
return null;
}
}
const BytesArrayBuilder = struct {
const Self = @This();
pub const Array = BytesArray;
data: ArrayList(u8),
offsets: ArrayList(u32),
validity: DynamicBitSet,
pub fn init(allocator: Allocator) !Self {
var offsets = try ArrayList(u32).initCapacity(allocator, 1);
offsets.appendAssumeCapacity(0);
return Self{
.data = ArrayList(u8).init(allocator),
.offsets = offsets,
.validity = try DynamicBitSet.initEmpty(allocator, 0),
};
}
fn append(self: *Self, v: Self.Array.Ref) !void {
try self.data.appendSlice(v);
try self.offsets.append(@intCast(u32, self.data.items.len));
try self.validity.resize(self.validity.capacity() + 1, true);
}
fn append_null(self: *Self) !void {
try self.offsets.append(@intCast(u32, self.data.items.len));
try self.validity.resize(self.validity.capacity() + 1, false);
}
pub fn finish(self: Self) BytesArray {
return BytesArray{
.data = self.data,
.offsets = self.offsets,
.validity = self.validity,
};
}
};
// 定义 DataType,假设我们支持五种类型。
const DataType = union(enum) {
SmallInt: void,
Integer: void,
BigInt: void,
Varchar: void,
Char: u16, // Char 的长度
// 关联逻辑类型和物理类型
fn ArrayType(self: DataType) type {
return switch (self) {
DataType.SmallInt => FixedArray(i16),
DataType.Integer => FixedArray(i32),
DataType.BigInt => FixedArray(i64),
DataType.Varchar => BytesArray,
DataType.Char => BytesArray,
};
}
};
@BruceChen7
Copy link
Author

BruceChen7 commented Jul 9, 2022

async in zig

// 阻塞模式
const net = @import("std").net;

pub fn main() !void {
    const addr = try net.Address.parseIp("127.0.0.1", 7000);
    try send_message(addr);
}

fn send_message(addr: net.Address) !void {
    var socket = try net.tcpConnectToAddress(addr);
    defer socket.close();

    _ = try socket.write("Hello World!\n");
}

const net = @import("std").net;

// 采用事件模型
pub const io_mode = .evented;

pub fn main() !void {
    const addr = try net.Address.parseIp("127.0.0.1", 7000);
    try send_message(addr);
}


// 非阻塞模式,没有着色问题
fn send_message(addr: net.Address) !void {
    var socket = try net.tcpConnectToAddress(addr);
    defer socket.close();

    _ = try socket.write("Hello World!\n");
}

着色问题

  • 由于你不能从非async代码中调用async函数,你最终会有很多重复的工作,你需要重新实现部分标准库和所有网络相关的库,以考虑到async/await。这方面的一个例子是Python,在Python 3中引入async/await后,诞生了aio-libs这样的项目,其目标是在AsyncIO之上重新实现流行的网络库。

@BruceChen7
Copy link
Author

pub const BoolParser = struct {
    // 是否支持
    pub fn isSupported(comptime T: type) bool {
        return switch (@typeInfo(T)) {
            .Bool, .Int, .Float => true,
            else => false,
        };
    }

    pub fn parse(comptime T: type, comptime _: type, msg: anytype) !T {
        const ch = try msg.readByte();
        try msg.skipBytes(2, .{});
        return switch (@typeInfo(T)) {
            else => unreachable,
            .Bool => ch == 't',
            .Int, .Float => if (ch == 't') @as(T, 1) else @as(T, 0),
        };
    }

    pub fn isSupportedAlloc(comptime T: type) bool {
        return isSupported(T);
    }

    pub fn parseAlloc(comptime T: type, comptime rootParser: type, allocator: std.mem.Allocator, msg: anytype) !T {
        _ = allocator;

        return parse(T, rootParser, msg);
    }
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment