整数集(intset.h/intset.c)

intset是集合键的底层实现之一, 保存的元素是有序的。

可作为集合键底层实现, 如果一个集合满足以下两个条件:

1 保存可转化为long long类型的元素

2 元素数量不多

数据结构

typedef struct intset {
    //保存元素所使用类型的长度
    uint32_t encoding;
    //保存元素的个数
    uint32_t length;
    //保存元素的数组
    int8_t contents[];
} intset;

添加元素

digraph intsetAdd {

    node [shape=plaintext, style = filled];

    edge [style = bold];

    start [label="intsetAdd", fillcolor = "#A8E270"];

    check_encoding [label="集合当前的encodeing\n是否小于sizeof(value)?", shape = diamond, fillcolor = "#95BBE3"];

    start -> check_encoding;

    upgrade [label="调用intsetUpgradeAndAdd升级集合"];

    check_encoding -> upgrade [label="小于"];
    
    upgrade_move [label="从后面开始移动元素\n并将新元素添加到升级后的集合中\nvalue小于0添加在最前面\nvalue大于0添加在最后"];
    upgrade -> upgrade_move;

    value_exists [label="元素已经存在于集合?", shape = diamond, fillcolor = "#95BBE3"];

    check_encoding -> value_exists [label="不小于"];


    insert_fail [label="添加失败success=0,元素已存在"];

    realloc_and_move [label="为新元素分配内存\n并对 contents 数组中现有的元素进行移动,\n确保新元素会被放到有序数组正确的位置上"];
    
    value_exists -> insert_fail [label="是"];

    value_exists -> realloc_and_move [label="否"];


    done [label="将新元素的值保存到 contents 数组中\n更新 length 计数器"];

    realloc_and_move -> done;
}

Note

intset初始化的时候是int16_t类型;只支持升级,不支持降级;查找使用二分查找法。