使用ConcurrentHashmap在多线程下完成键值信息的查找维护
===================================

FAST Kit提供的Concurrent HashMap（并发哈希表）专为高并发场景下的键值对数据管理而设计。主要用于实现多线程环境下的安全存储、快速访问与高效更新，适用于对并发吞吐量和数据一致性要求较高的增删改查操作，典型场景包括单点插入、删除、查询及并发修改等。

#### 接口说明

具体API说明详见[接口文档](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast)。

| 名称 | 描述 |
| :-- | :-- |
| [FAST\_ErrorCode](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_errorcode-1) [HMS\_FAST\_ConcurrentHashmap\_Create](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_create) ([FAST\_ConcurrentHashmapHandle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmaphandle)\* handle, [HMS\_FAST\_ConcurrentHashmap\_HashFunc](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_hashfunc) hasher, [HMS\_FAST\_ConcurrentHashmap\_KeyEqualFunc](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_keyequalfunc) equaler, float maxLoadFac, size\_t numShards) | 使用给定配置创建并发哈希表。 |
| void [HMS\_FAST\_ConcurrentHashmap\_Destroy](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_destroy) ([FAST\_ConcurrentHashmapHandle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmaphandle)\* handle) | 销毁指定并发哈希表。 |
| [FAST\_ErrorCode](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_errorcode-1) [HMS\_FAST\_ConcurrentHashmap\_Insert](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_insert) ([FAST\_ConcurrentHashmapHandle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmaphandle)\* handle, const [FAST\_ConcurrentHashmapKeyPtr](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmapkeyptr) key, const [FAST\_ConcurrentHashmapValuePtr](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmapvalueptr) value, [FAST\_ConcurrentHashmapValuePtr](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmapvalueptr)\* originValue) | 将给定的键值对插入并发哈希表中，如果键已经存在，则使用value覆写原有的值，并将对应值的地址保存在originValue中。 |
| [FAST\_ErrorCode](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_errorcode-1) [HMS\_FAST\_ConcurrentHashmap\_Find](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_find) ([FAST\_ConcurrentHashmapHandle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmaphandle)\* handle, const [FAST\_ConcurrentHashmapKeyPtr](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmapkeyptr) key, [FAST\_ConcurrentHashmapValuePtr](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmapvalueptr)\* value) | 在给定并发哈希表中查找输入的键，并将对应的值保存在value中。 |
| [FAST\_ErrorCode](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_errorcode-1) [HMS\_FAST\_ConcurrentHashmap\_Erase](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_erase) ([FAST\_ConcurrentHashmapHandle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmaphandle)\* handle, const [FAST\_ConcurrentHashmapKeyPtr](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmapkeyptr) key, [FAST\_ConcurrentHashmapKeyPtr](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmapkeyptr)\* originKey, [FAST\_ConcurrentHashmapValuePtr](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmapvalueptr)\* originValue) | 在给定哈希表中删除输入的键，并将键/值对应的地址保存在originKey和originValue中。 |
| [FAST\_ErrorCode](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_errorcode-1) [HMS\_FAST\_ConcurrentHashmap\_TryInsert](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_tryinsert) ([FAST\_ConcurrentHashmapHandle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmaphandle)\* handle, const [FAST\_ConcurrentHashmapKeyPtr](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmapkeyptr) key, const [FAST\_ConcurrentHashmapValuePtr](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmapvalueptr) value) | 将给定的键值对插入并发哈希表中，如果键已经存在、则不做操作。 |
| size\_t [HMS\_FAST\_ConcurrentHashmap\_Size](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_size) ([FAST\_ConcurrentHashmapHandle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmaphandle)\* handle) | 返回给定哈希表当前的元素个数。 |
| void [HMS\_FAST\_ConcurrentHashmap\_Clear](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_clear) ([FAST\_ConcurrentHashmapHandle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmaphandle)\* handle) | 清空给定哈希表中维护的所有元素。 |
| size\_t [HMS\_FAST\_ConcurrentHashmap\_EraseIf](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_eraseif) ([FAST\_ConcurrentHashmapHandle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmaphandle)\* handle, [HMS\_FAST\_ConcurrentHashmap\_HookFunc](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_hookfunc) condFunc, void\* condCtx, [HMS\_FAST\_ConcurrentHashmap\_HookFunc](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_hookfunc) freeFunc, void\* freeCtx) | 删除哈希表中符合开发者定义条件的所有元素，并使用开发者定义的方式释放其内存。 |
| void [HMS\_FAST\_ConcurrentHashmap\_Traverse](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_traverse) ([FAST\_ConcurrentHashmapHandle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#fast_concurrenthashmaphandle)\* handle, [HMS\_FAST\_ConcurrentHashmap\_HookFunc](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_hookfunc) condFunc, void\* condCtx, [HMS\_FAST\_ConcurrentHashmap\_HookFunc](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/fast-kit-fast#hms_fast_concurrenthashmap_hookfunc) workFunc, void\* workCtx) | 遍历哈希表，将所有符合开发者输入条件的键值对按开发者给定的方式修改。 |

#### 开发步骤

1.  在CMake脚本中链接相关动态库。
    
     find\_library(
         lib\_fast\_ads
         NAMES fast\_ads
     )
    target\_link\_libraries(entry PRIVATE ${lib\_fast\_ads})
    
2.  调用相关接口能力完成键值信息的管理。
    
    #include "FASTKit/fast\_ads\_concurrent\_hashmap.h"
    
    // 定义哈希值如何计算，键如何比较
    uint64\_t custom\_hash\_int(const FAST\_ConcurrentHashmapKeyPtr key) {
        static std::hash<int> hasher;
        int\* intKey = (int\*)key;
        return hasher(\*intKey);
    }
    
    int32\_t custom\_equal\_int(const FAST\_ConcurrentHashmapKeyPtr key1, const FAST\_ConcurrentHashmapKeyPtr key2) {
        int\* intKey1 = (int\*)key1;
        int\* intKey2 = (int\*)key2;
        return (\*intKey1) == (\*intKey2);
    }
    
    // 自定义删除条件
    int32\_t custom\_erase\_cond(FAST\_ConcurrentHashmapKeyPtr key, FAST\_ConcurrentHashmapValuePtr val, void\* context) {
        return 1;
    }
    
    // 释放键和值指针持有的内存
    int32\_t custom\_free(FAST\_ConcurrentHashmapKeyPtr key, FAST\_ConcurrentHashmapValuePtr val, void\* context) {
        int\* intKey = (int\*)key;
        int\* intVal = (int\*)val;
        delete intKey;
        delete intVal;
        return 0;
    }
    
    // 自定义修改条件，也可传入nullptr以对所有元素执行修改
    int32\_t custom\_modify\_cond(FAST\_ConcurrentHashmapKeyPtr key, FAST\_ConcurrentHashmapValuePtr val, void\* context) {
        return 1;
    }
    
    int32\_t custom\_work(FAST\_ConcurrentHashmapKeyPtr key, FAST\_ConcurrentHashmapValuePtr val, void\* context) {
        int\* intVal = (int\*)val;
        int\* intCtx = (int\*)context;
        \*intVal += (\*intCtx);
        return 1;
    }
    
    static napi\_value RunConcurrentHashmap(napi\_env env, napi\_callback\_info info)
    {
        // 使用合适的配置创建并发哈希表，负载因子（loadfac）和分段数（numShards）的典型值一般为0.8和64。
        // 负载因子主要作用于分段内部，更大的负载因子通常意味着更小的内存消耗和更大的操作开销；
        // 分段数主要作用域并发哈希表全局，更大的分段数通常意味着更好的并发性能和更大的内存消耗
        FAST\_ConcurrentHashmapHandle handle;
        HMS\_FAST\_ConcurrentHashmap\_HashFunc hasher = &custom\_hash\_int;
        HMS\_FAST\_ConcurrentHashmap\_KeyEqualFunc equaler = &custom\_equal\_int;
        float loadfac = 0.8;
        size\_t numShards = 64;
        int ret = HMS\_FAST\_ConcurrentHashmap\_Create(&handle, hasher, equaler, loadfac, numShards);
    
        // 初始化空的哈希表并向其中插入元素
        const int size = 10;
        int keys\[size\] = {1,2,3,4,5,6,7,8,9,10};
        int vals\[size\] = {1,2,3,4,5,6,7,8,9,10};
        for (int i = 0; i < size; ++i) {
            ret = HMS\_FAST\_ConcurrentHashmap\_Insert(
                handle,
                (FAST\_ConcurrentHashmapKeyPtr)&(keys\[i\]),
                (FAST\_ConcurrentHashmapValuePtr)&(vals\[i\]),
                nullptr
            );
        } // 完成插入后哈希表中应包含 {1: 1, 2: 2, ..., 10: 10}
        
        // 使用insert覆写已有的key，如果使用tryInsert则不会覆写
        int key2 = 1;
        int val2 = 2;
        int\* originVal0;
        ret = HMS\_FAST\_ConcurrentHashmap\_Insert(
            handle,
            (FAST\_ConcurrentHashmapKeyPtr)&key2,
            (FAST\_ConcurrentHashmapValuePtr)&val2,
            (FAST\_ConcurrentHashmapValuePtr\*)&originVal0
        ); // {1: 2, ...}, 且originVal0 == &vals\[0\]
    
        // 键查找对应的值，并将结果保存在输入指针中。开发者需注意在使用此接口时应校验返回值ret，
        // 如果ret值不等于FAST\_ERROR\_CODE\_SUCCESS，则res获取到的值是无效的
        int targetKey = 1;
        int\* res;
        ret = HMS\_FAST\_ConcurrentHashmap\_Find(
            handle,
            (FAST\_ConcurrentHashmapKeyPtr)&targetKey,
            (FAST\_ConcurrentHashmapValuePtr\*)&res
        ); // (\*res) == 2
    
        // 键删除并发哈希表中对应的键值对，并获取关联内存的地址
        // 可以使用originKey/Val获得预先插入的元素地址，便于内存管理，可以使用nullptr作为入参
        int\* originKey1;
        int\* originVal1;
        int deleteKey = 1;
        ret = HMS\_FAST\_ConcurrentHashmap\_Erase(
            handle,
            (FAST\_ConcurrentHashmapKeyPtr)&deleteKey,
            (FAST\_ConcurrentHashmapKeyPtr\*)&originKey1,
            (FAST\_ConcurrentHashmapValuePtr\*)&originVal1
        ); // originKey1 == &keys\[0\] && originVal1 == &val2
    
        // 查询并发哈希表当前元素个数
        size\_t curSize = HMS\_FAST\_ConcurrentHashmap\_Size(handle); // curSize == 9
    
        // 清空并发哈希表中所有元素
        HMS\_FAST\_ConcurrentHashmap\_Clear(handle);
        curSize = HMS\_FAST\_ConcurrentHashmap\_Size(handle); // curSize == 0
    
        for (int i = 0; i < 6; i++) {
            int\* key = new int{i};
            int\* val = new int{i};
            ret = HMS\_FAST\_ConcurrentHashmap\_Insert(
                handle,
                (FAST\_ConcurrentHashmapKeyPtr)key,
                (FAST\_ConcurrentHashmapValuePtr)val,
                nullptr
            );
        } // {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5}
    
        // 使用Traverse接口对符合custom\_modify\_cond的元素执行custom\_work操作
        int context = 10;
        HMS\_FAST\_ConcurrentHashmap\_Traverse(
            handle,
            (HMS\_FAST\_ConcurrentHashmap\_HookFunc)&custom\_modify\_cond,
            nullptr,
            (HMS\_FAST\_ConcurrentHashmap\_HookFunc)&custom\_work,
            (void\*)&context
        ); // {0: 10, 1: 11, 2: 12, 3: 13, 4: 14, 5: 15}
    
        // 使用EraseIf接口删除所有符合custom\_erase\_cond的键值对并使用custom\_free清理相应的内存
        ret = HMS\_FAST\_ConcurrentHashmap\_EraseIf(
            handle,
            (HMS\_FAST\_ConcurrentHashmap\_HookFunc)&custom\_erase\_cond,
            nullptr,
            (HMS\_FAST\_ConcurrentHashmap\_HookFunc)&custom\_free,
            nullptr
        ); // size == 0 && ret == 6
    
        // 销毁并发哈希表
        HMS\_FAST\_ConcurrentHashmap\_Destroy(handle);
        return 0;
    }