对于熟悉 c99 的人来说,Designated Initializers 并不算是什么新鲜事物,然而 c++直到 c++20 才正式支持这一特性。 虽然在 c++20 之前,像 GCC 这样的编译器通过扩展的形式已经对该特性做了支持,但是随着 c++20 将其纳入新标准,这一特性将在所有编译器中得到支持。

基本用法

Designated Initialization 是聚合初始化(Aggregate Initialization)的一种形式。 在 c++20 中,聚合类型(Aggregate types)是指:

  • 数组类型
  • 具备如下特性的 class 类型:
    • has no private or protected...

前言

做存储开发,一定会经常涉及到 IO 相关的操作。而现在的高级编程语言,往往会帮助我们屏蔽 IO 操作的底层细节,虽然这样能降低开发门槛,提升效率,但是却也导致我们对 IO 底层操作实现的理解不够系统和深入。 所以呢,我一直想抽时间来系统整理一下 Linux IO 涉及的系统调用,以及相互之间的区别和联系,以加深对 IO 操作的理解。

IO 操作

fwrite

fwrite 是 c 语言标准库中的文件写入函数,其作用是向指定的文件中写入若干数据。调用 fwrite 实际上是将数据写入到了 c 标准库的 IO Buffer 中。

mmap

mmap 将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是...

对于一个标准的 c++容器来说,我们可以很容易在运行时使用迭代器和 range-based for loop 来遍历其中的每一个元素。但是对于std::tuple,却不能像普通的容器那样去遍历它。

std::tuple 简介

std::tuple是一个具有固定大小,包含不同类型值的集和。与之相似的是std::pair,只不过std::pair只能容纳两个元素, 而std::tuple可以容纳许多元素:

std::tuple<int, double, const char*> tup {42, 10.5, "hello"};

// or with CTAD(class template argument...

string_view 简介

std::string_view是 c++17 中新增的一种类型。其核心理念是,能够让我们在传统的 C++03 风格的具体性和泛型编程之间找到一个很好的折衷点。 在 C++17 标准之前,我们通常只能在粗糙的不严谨的模板实现和相对严谨但是有着冗长约束的模板之间做出选择。举个简单的例子:

// c++03 style
class Widget
{
    std::string name_;

public:
    void setName(const char* new_name);
    void setName(const std::string& new_name);
};

// ...

1. 概览

要谈论 LevelDB 的 Compaction 就不得不从 LevelDB 的整个数据写入流程入手。LevelDB 的基本写入流程大致为:

  1. 数据先写入到 WAL 日志中,做持久化
  2. 然后数据同步到mutable memtable
  3. mutable memtable大小达到Options.write_buffer_size设置的大小时,就会变成immutable memtable,并且创建一个新的mutable memtable
  4. 后台的 Compaction 线程会把immutable memtabledump 成 sstable 文件,并设置于 Level 0 层
  5. 当 Level i 达到一定条件后,...

拜占庭将军问题

简介

  • 在可能存在叛军的情况下,采用合适的通讯协议,让多个将军达成共识,执行统一的作战计划
  • 二忠一叛难题
  • 它是分布式领域最复杂的容错模型
  • 莱斯利·兰伯特(Leslie Lamport)The Byzantine Generals Problem

二忠一叛难题

  • 总共有三个将军,其中一个作为指挥官
  • 通过信使相互传递作战指令,进攻或者撤退
  • 所有忠诚的将军必须执行统一的作战计划,忠诚的将军必须执行忠诚的指挥官发布的指令
  • 假如 LIEUTENANT2 叛变,LIEUTENANT1 收到的作战指令就是“进攻,撤退”
  • 假如 COMMANDER 叛变,LIEUTENANT1 和 LIEUTENANT2 收到...

使用 c 语言的 macro 操作,能够很简单的用 c 语言模拟 lisp 语法。

下面我们来定义 lisp.h 头文件

#ifndef LISP_H_OTE1HWPK
#define LISP_H_OTE1HWPK

#include <stdio.h>
#include <stdlib.h>

#define define(ret, name, args, block) \
    ret name args { return block; }

#define if(expr, block1, block2) \
    expr ? block1 : block2

#define eq(a, b)...

开始之前

这篇文章主要是为了帮助大家熟悉 POSIX 线程库以及在实际开发中使用它的特性。我们会具体讲解如何利用这个线程库定义的不同工具 来解决编程中的问题。当然这里隐含了一个假设,就是读者已经了解过并行编程(或者多进程)的相关概念,如果没有这些背景知识 的话,读者可能会感觉到很难理解。不过也没关系,我的另一篇教程里边有专门为只具备线性编程思维的读者提供了对并行编程理论 和相关术语的讲解。

同样的,我假设聪明的你已经熟悉了异步编程模型,那些经常使用桌面环境的人会更容易去接受多线程编程的理念。

当我们谈到 POSIX 线程的时候,肯定会有人心生疑惑:“我们应该使用哪个标准下的 POSIX 线程?”。由于 POSIX 线程标准已经修订...

原文地址:http://nikic.github.io/2014/02/18/Fast-request-routing-using-regular-expressions.html

前一些日子,我发现了一个叫做Pux的路由库,这个路由库声称自己比现有的路由要快很多,为了实现这个特点,该库使用了 C 语言编写了 PHP 扩展。

然而,当我瞅了几眼它的代码后,我非常怀疑这个库在路由过程中做了错误的优化,而且我能够很容易在不适用扩展的情况下做出更高性能的实现。 当我在看了 benchmarking 代码后更加确定了我的怀疑,因为我发现这里仅仅只是对及其确定的单个路由做了测试。

为了进一步研究这个问题,我写了一个轻量的路由库:...