轻量级高并发网络库+httpserver

本博客部署在两个服务器上,其中一个的 HTTP 服务就是由本文介绍的 FalconLink 提供。你可以通过IP地址 101.34.211.126:20080 尝试访问。 项目地址 https://github.com/caaatch22/FalconLink Overview FalconLink是一个轻量级的高并发网络库。它封装了网络编程套接字API,将其抽象成一个易用,可拓展框架。用户只需通过设置回调函数的形式注入业务逻辑。它同时也具有 HTTP 服务请求与解析的功能。 上图是FalconLink系统架构的一个简单概括性图示。 采用非阻塞socket配合边缘触发,及one loop per thread的主从 reactor设计 Acceptor 是专门用于处理接受新用户连接请求的模块。它守候在监听端口。收到请求后建立 Connection 分配给 EventLoop。 FalconLink 将每个 TCP连接抽象成一个 Connection,一个 Connection对应一个连接 socket 套接字。用户可以为每一条Connection注册回调函数。 每个 EventLoop 都拥有一个 Poller。 Poller 负责监听已连接的套接字,将有事件触发的连接反馈给 EventLoop。 EventLoop是该系统的核心组件, 每个都单独运行在一个线程中. 它从 Poller 中接收到有事件触发的用户连接后, 会获取并执行它们的回调函数. ThreadPool 线程池管理着系统中有多少个 EventLoop 在运行,并调度线程,防止注册过多线程导致性能下降。 支持 HTTP(GET,HEAD)请求的解析与回复,支持挂载静态 html 文件(本博客使用FalconLink的 HTTP 服务) 实现异步logger API 使用falconlink,可以轻易且优雅的在20行内实现一个 echo server。 #include "falconlink.hpp" int main() { falconlink::InetAddr local_address("0.0.0.0", 8090); falconlink::Server echo_server(local_address); echo_server .onHandle([&](falconlink::Connection* client_conn) { int from_fd = client_conn->fd(); auto [read, exit] = client_conn->recv(); if (exit) { client_conn->getEventLoop()->deleteConnection(from_fd); // client_conn ptr is invalid below here, do not touch it again return; } // 只有以下四行是业务逻辑 if (read) { client_conn->WriteToWriteBuffer(client_conn->ReadAsString()); client_conn->send(); client_conn->clearReadBuffer(); } }) .start(); return 0; } Build & Test 将代码 clone 到本地,进入主目录 ...

March 1, 2023 · 1 min

CMU15445-project3 Query Excution

Overview 在这次实验写完后,我们已经能使用bustub-shell完成执行 sql 语句了,还是挺有成就感的。同时,TA 为我们准备了浏览器上的bustub ,方便和我们写的对比调试。你也可以使用 explain 来查看他的优化策略与执行步骤。 这次实验的主要难点在于读代码,理清 bustub 的执行引擎的数据流以及代码中的实现。搞懂了之后各个算子的实现就很简单了(相对 B+树)。 上图是 bustub 的整体架构。 Parser sql 语句的解析就像其他编程语言一样,同样需要翻译成比较结构化的东西。Parser 阶段会生成一个抽象语法树(AST, Abstract Syntax Tree)。 这并不是数据库核心部分,bustub 直接使用了 PostgreSQL 的 parser 库 libpg_query。 Binder 得到 AST 后,需要将这些词语绑定到数据库实体上,这就是 Binder 的工作。例如有这样一条 sql: SELECT table1.y, table2.x FROM table1 INNER JOIN table2 ON table1.x = table2.y; 其中 SELECT 和 FROM 是关键字,x 和 table1 是标识符。我们可以使用 explain 来看看 binder 层(bustub-shell 未完成时也可以使用 explain): === BINDER === BoundSelec { table=BoundJoin { type=Inner, left=BoundBaseTableRef { table=table1, oid=25 }, right=BoundBaseTableRef { table=table2, oid=26 }, condition=(table1.x=table2.y) }, columns=[table1.y, table2.x], groupBy=[], having=, where=, limit=, offset=, order_by=[], is_distinct=false, ctes=, } 可以看出,binder的作用就是对AST的各个节点绑定一个(物理)实体。 ...

January 17, 2023 · 4 min

将Wavelet Tree用于算法竞赛

Wavelet Tree for Competitive Programming 最近在学FM-Index相关算法用于数据库,了解到Wavelet Tree这一数据结构,发现其还可以应用在算法竞赛中。网上相关中文资料比较少,权当自己做个学习笔记 开始之前 在学习wavelet tree前,不妨看看他能解决什么样的问题。 假设我们有一长为 $n$ 的序列 $A[0…n - 1]$ 。在算法竞赛中,典型的数据量是 $n = 1e5, |A[i]| <= 1e9$ 区间 $[L, R)$ 中元素$x$的出现次数 区间 $[L, R)$ 中的第k小数 区间 $[L, R)$ 上 小于等于x的数的个数 … 以上问题都可以通过可持久化线段树在解决。那为什么还需要wavelet tree呢,我们都知道可持久化线段树的常数很大,并且十分消耗空间,在有些苛刻的题目下可能会被卡 好吧应该都是金牌题,不是我该考虑的 。利用wavelet tree可以在$log(\sigma)$时间内完成的同时(且优秀的常数),若使用bitvector优化空间,空间上大概比可持久化线段树少一个量级。最重要的一点是,我个人觉得他比主席树更加直观易懂。 $\sigma$ = | $\Sigma = {1, 2, \cdots, \sigma}$| (用于序列上时是值域大小)。 用wavelet tree的缺点就是带修改操作比较难写,码量较大,一般不会在比赛时使用。 Wavelet Tree 该图给出了用序列 $A = [7, 3, 5, 6, 1, 3, 2, 7, 8, 4]$ 构建的wavelet tree的形态。对于树上的每个节点,我们会将其按照值域分成两个部分$[low, mid), [mid, high)$。通过 稳定划分(stable_partition,即不改变相对顺序的情况下划分)将该节点上的序列中小于 $mid$的划分到左子树中,大于等于mid的划分到右子树中,递归直至节点中只有一种值时为叶节点。需要注意的是,我们并不会在叶子节点中直接存储序列的值,而是通过某个方法使得我们能够使用较小的空间的情况下得到足够的信息。 ...

January 10, 2023 · 4 min

CMU15445-project2 Concurrent B+ tree

Overview 这个实验应该是最难的一个实验了。。。(感觉和Project 4 —— Transaction实现的难度差不多) 另外,2022fall版本的B+ tree更是变态,因为几乎没有给任何内部的API,让人无从下手。建议到 Github repo 里找到20年的,我基本是根据里面定义的函数来实现的。 实验材料贴心的为你分成了两个检查点,四个小任务。 Checkpoint #1 Task #1 - B+Tree Pages Task #2 - B+Tree Data Structure (Insertion, Deletion, Point Search) Checkpoint #2 Task #3 - Index Iterator Task #4 - Concurrent Index Task #1 - B+Tree Pages 第一个任务算是热身,主要是搞清楚 B+ 树的一些类之间的关系。 我们知道,数据库中的索引也是数据,同样以 page 的形式被组织。我们先来看看要完成的这些类之间的关系。 B+ tree internal page 与 B + tree leaf page 都继承自B + tree page,B + tree page 中定义了 B+ 树每个结点的一些信息。而B + Tree 这个类则是Checkpoint 1的主要对象,它对internal page 以及 leaf page 进行管理,并对外开放接口。而在内存中,internal page 与 leaf page 都属于 page 的一部分,关系如下图所示。他们就是 page 中的 data 部分。因此,每次 从 buffer pool manager 得到一个 page 后,若是将他们用作 B+树的结点,则需要对这个 data 进行释义,也就是将他强制转化为internal page 或者 leaf page。这在 C++ 中通过 reinterpret_cast 完成。 ...

December 27, 2022 · 2 min

CMU15445-project1 Buffer Pool Manager

Buffer Pool Manager cmu15445 是一门关于数据库管理系统(DBMS)设计与实现的经典公开课,是很多dba和内核开发人员的入门课程。开课教授Andy Pavlo 非常风趣幽默,他有自己上课的DJ,他曾在浴缸里录课,且时常语出惊人。这门课的实验项目BusTub非常有挑战性,并对所有人开放评测资源。 Overview BusTub是一个面向磁盘的 DBMS(Database Management System)。由于磁盘上的数据不支持字节粒度的访问,这就需要一个管理页的中间层,而 Andy 坚持“The OS is not your friend”, 反对使用 mmap 进行页操作,因此实验一的目标便在于通过实现 Buffer Pool Manager 主动管理磁盘中的页(page)在内存中的缓存,从而,最小化磁盘访问次数(时间上)、最大化相关数据连续(空间上)。 这次实验有三个子任务,分别是 Task #1: Extendible Hash Table Task #2: LRU-K Replacer Task #3: Buffer Pool Manager Instance 可拓展哈希表是这个是实验中相对独立的模块。这里不会讲它的细节,后面的两个任务中需要用到哈希表的地方我直接用std::unordered_map替代,而且效率还更高。应该是因为 Extendible Hash Table 要求线程安全,为了方便在我在每个函数入口都加了大锁。 想要 Extendible Hash Table 具体细节的可以看这个b站视频。关于它的优化,我想可以进行更细粒度的锁管理甚至写一个无锁(lockfree)的哈希表。 Buffer Pool Manager 在后两个实验开始之前,我建议先将Task #2和Task #3的实验材料完整的看完在开始写代码。因为 replacer 和 buffer pool manager 有较大程度的耦合。很多API设计需要对照两个组件才能知道自己应该维护的数据与功能的边界。为了更符合直觉,我会先阐述 buffer pool manager 的设计,同时会穿插着 LRU-k 的API什么时候,在哪用。 ...

December 22, 2022 · 3 min

个人常用配置备忘

vscode 插件: C/C++, ~ Extension Pack, Themes, InteliCode CMake Tools, CodeLLDB Vim remote ssh, docker Error Lens, GitLens user的settings.json "editor.fontFamily": "Fira Code", "workbench.panel.defaultLocation": "right", "vim.handleKeys": { "<C-c>": false, "<C-f>": false, "<C-x>": false, "<C-a>": false, "<C-p>": false, }, "C_Cpp.vcFormat.newLine.beforeOpenBrace.block": "sameLine", "C_Cpp.vcFormat.newLine.beforeOpenBrace.function": "sameLine", "editor.formatOnSave": true, "C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: LLVM, UseTab: Never, IndentWidth: 2, TabWidth: 2}", pip, python, pyenv 使用pyenv控制多个python版本 pyenv versions # 查看所有安装的python脚本 pyenv install 3.8.0 # 安装python 3.8.0 pyenv global 3.8.0 # 将3.8.0设置为全局python,对应pip也会改变 删除__pycache__ find . -name "*.pyc" -type f -print -exec rm -rf {} \; about clash # start.sh nohup ./clash -d . >/dev/null 2>&1 & #shutdown.sh ps -A | grep clash | awk '{print $1}' | xargs kill 暂时设置7890做全局代理 ...

December 20, 2022 · 1 min

cs144-note1

Computer Network introduction dominant model : bidirectional, reliable byte stream connection http: hypertext transfer protocol : designed to be a document centric way for programs to communicate. Client —> Server model Bit-Torrent: (peer-to-peer model) a client requests document from other clients, a single client can request from many others. these collections of collaborating clients are called swarms when a client wants to downloads a file, it first find torrent, usually using www and download using http. torrent file describes information about data file, also tells bit-torrent about the tracker (a node keeps track names of clients of the swarm) ...

May 9, 2022 · 3 min

xcpc template

icpc模板 Previous Next     / [pdf] View the PDF file here. algorithm-template Competitive Programming template ...

March 17, 2022 · 1 min