位图法

定义位图法即 bitmap,就是用一个 bit 位来标记某个元素对应的 Value,而 Key 即是该元素。由于采用了 Bit 为单位来存储数据,因此在内存占用方面,可以大大节省。适用于大规模数据,但数据状态不是很多的情况。通常是用来判断某个数据存不存在。实现应用100亿整型数据去重整型数据为 32

定义

位图法即 bitmap,就是用一个 bit 位来标记某个元素对应的 Value,而 Key 即是该元素。由于采用了 Bit 为单位来存储数据,因此在内存占用方面,可以大大节省。适用于大规模数据,但数据状态不是很多的情况。通常是用来判断某个数据存不存在

实现

应用

求集合的所有子集

集合有 n 个元素,它的子集的个数就是对这 n 个元素做组合,一共有n个位置可以组合,每个位置上该元素可以出现也可以不出现,所以最后总的个数为2的n次方。

这种状态只有两个,一共有 n 个位置的情况,完全适合适用位图。

对照图

因此只需要从 0 遍历到 2^n,即可将所有的子集遍历出来。然后再针对每一个值,去出相应位上的 bit 值,0 不出现在子集中,1 出现在子集中。

100亿整型数据去重

整型数据为 32 位最多有 2^32 (42亿多),所以 100 亿整型数据一定有重复的,2^32 个整形用位表示,需要 (2^32)bit == 512MB,需要 512MB 内存表示。

#include <stdio.h>
#include <stdlib.h>
 
#define MAX (0xffffffff)

/* 根据num将对应的MAP的bit位置1 */
void setBuf(char *buf, unsigned int num)
{
    *(buf+(num>>0x3)) |= (0x1<<(num&0x7));
    return;
}

/* 获取num对应的MAP的bit位值 */
unsigned int getBuf(char *buf, int num)
{
    unsigned int flag = 0;
    flag = ((*(buf+(num>>0x3)) & (0x1<<(num&0x7))) != 0)? 1:0;
    return flag;
}
 
int main(int argc,char **argv)
{
    if(argc < 2)
    { 
        printf("usage:./a {0-9}*\n");
        return 0;
    }
    unsigned int index = 1;
    unsigned int num;
    unsigned int max = 0;
    char* buf = (char*)calloc((MAX>>0x3)+1,sizeof(char));
    while(index < argc)    
    {
        num = atoi(argv[index]);
        max = max>num? max:num;
        setBuf(buf,num);
        ++index;
    }
    for(index = 0; index <= max; index++)
    {   
        if(getBuf(buf,index) == 1)
        {
           printf("id:%-10u flag:0x%-16x value:%-10u state:%-2d\n",
                   index>>0x3,
                   (unsigned int)buf[index>>0x3],
                   index,
                   getBuf(buf,index));
        }
        printf("process[%u]:%.2f%%\r",index,(float)(index)/max*100);
    }
    printf("\n");
    return 0;
}

参考

Read more

容器镜像(4):镜像的常用工具箱

容器镜像(4):镜像的常用工具箱

前几篇在讲多架构镜像时已经用过 skopeo 和 crane 做镜像复制,这篇系统整理这两个工具的完整能力,同时介绍几个日常操作镜像时同样好用的工具。 一、skopeo:不依赖 Daemon 的镜像瑞士军刀 skopeo 的核心价值是绕过 Docker daemon,直接与 Registry API 交互。上一篇用它做镜像复制和离线传输,但它的能力远不止于此。 1.1 安装 # Ubuntu / Debian sudo apt install -y skopeo skopeo --version # skopeo version 1.15.1 1.2 inspect:免拉取检查镜像元数据 docker inspect 需要先把镜像拉到本地,skopeo inspect 直接向 Registry

容器镜像(3):多架构镜像构建

容器镜像(3):多架构镜像构建

一、什么是多架构镜像 1.1 OCI Image Index 上一篇介绍了单平台镜像的结构:一个 Manifest 指向 Config 和若干 Layer blob。多架构镜像在此之上多了一层——OCI Image Index(也叫 Manifest List),是一个轻量的索引文件,把多个单平台 Manifest 组织在一起: $ docker manifest inspect golang:1.22-alpine { "schemaVersion": 2, "mediaType": "application/vnd.oci.image.index.v1+json", "manifests&

容器镜像(2):containerd 视角下的镜像

容器镜像(2):containerd 视角下的镜像

一、为什么需要了解 containerd 如果你只用 docker run 跑容器,从来不关心底层,那可以不了解 containerd。但如果你在用 Kubernetes,或者想真正理解"容器运行时"是什么,containerd 是绕不开的。 事实上,当你执行 docker run 的时候,containerd 早就在后台悄悄工作了——Docker 从 1.11 版本开始,就把核心运行时剥离出来交给 containerd 负责。 1.1 Docker 的架构演变 早期的 Docker(1.10 及之前)是一个"大一统"的单体程序:一个 dockerd