## Coverage Report

#### Created: 2026-04-03 17:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /home/liu/actions-runner/_work/ccv/ccv/lib/ccv_cache.c

    Line
    Count
    Source
    1
    #include "ccv.h"
    2
    #include "ccv_internal.h"
    3
    4
    5.06M
    #define CCV_GET_CACHE_TYPE(x) ((x) >> 60)
    5
    86.6M
    #define CCV_GET_TERMINAL_AGE(x) (((x) >> 32) & 0x0FFFFFFF)
    6
    4.53M
    #define CCV_GET_TERMINAL_SIZE(x) ((x) & 0xFFFFFFFF)
    7
    5.06M
    #define CCV_SET_TERMINAL_TYPE(x, y, z) (((uint64_t)(x) << 60) | ((uint64_t)(y) << 32) | (z))
    8
    9
    void ccv_cache_init(ccv_cache_t* cache, size_t up, int cache_types, ccv_cache_index_free_f ffree, ...)
    10
    4
    {
    11
    4
      cache->rnum = 0;
    12
    4
      cache->age = 0;
    13
    4
      cache->up = up;
    14
    4
      cache->size = 0;
    15
    4
      assert(cache_types > 0 && cache_types <= 16);
    16
    4
      va_list arguments;
    17
    4
      va_start(arguments, ffree);
    18
    4
      int i;
    19
    4
      cache->ffree[0] = ffree;
    20
    7
      for (i = 1; i < cache_types; i++3)
    21
    3
        cache->ffree[i] = va_arg(arguments, ccv_cache_index_free_f);
    22
    4
      va_end(arguments);
    23
    4
      memset(&cache->origin, 0, sizeof(ccv_cache_index_t));
    24
    4
    }
    25
    26
    static int bits_in_16bits[0x1u << 16];
    27
    static int bits_in_16bits_init = 0;
    28
    29
    65.5k
    static int sparse_bitcount(unsigned int n) {
    30
    65.5k
      int count = 0;
    31
    589k
      while (n) {
    32
    524k
        count++;
    33
    524k
        n &= (n - 1);
    34
    524k
      }
    35
    65.5k
      return count;
    36
    65.5k
    }
    37
    38
    1
    static void precomputed_16bits() {
    39
    1
      int i;
    40
    65.5k
      for (i = 0; i < (0x1u << 16); i++65.5k)
    41
    65.5k
        bits_in_16bits[i] = sparse_bitcount(i);
    42
    1
      bits_in_16bits_init = 1;
    43
    1
    }
    44
    45
    62.7M
    static uint32_t compute_bits(uint64_t m) {
    46
    62.7M
      return (bits_in_16bits[m & 0xffff] + bits_in_16bits[(m >> 16) & 0xffff] +
    47
    62.7M
          bits_in_16bits[(m >> 32) & 0xffff] + bits_in_16bits[(m >> 48) & 0xffff]);
    48
    62.7M
    }
    49
    50
    /* update age along a path in the radix tree */
    51
    static void _ccv_cache_aging(ccv_cache_index_t* branch, uint64_t sign)
    52
    4.53M
    {
    53
    4.53M
      if (!bits_in_16bits_init)
    54
    0
        precomputed_16bits();
    55
    4.53M
      int i;
    56
    4.53M
      uint64_t j = 63;
    57
    4.53M
      ccv_cache_index_t* breadcrumb[10];
    58
    17.4M
      for (i = 0; i < 10; i++12.9M)
    59
    17.4M
      {
    60
    17.4M
        breadcrumb[i] = branch;
    61
    17.4M
        int leaf = branch->terminal.off & 0x1;
    62
    17.4M
        int full = branch->terminal.off & 0x2;
    63
    17.4M
        if (leaf)
    64
    1.47M
        {
    65
    1.47M
          break;
    66
    15.9M
        } else {
    67
    15.9M
          ccv_cache_index_t* set = (ccv_cache_index_t*)(branch->branch.set - (branch->branch.set & 0x3));
    68
    15.9M
          int dice = (sign & j) >> (i * 6);
    69
    15.9M
          if (full)
    70
    9.38M
          {
    71
    9.38M
            branch = set + dice;
    72
    9.38M
          } else {
    73
    6.60M
            uint64_t k = 1;
    74
    6.60M
            k = k << dice;
    75
    6.60M
            if (k & branch->branch.bitmap) {
    76
    3.54M
              uint64_t m = (k - 1) & branch->branch.bitmap;
    77
    3.54M
              branch = set + compute_bits(m);
    78
    3.54M
            } else {
    79
    3.06M
              break;
    80
    3.06M
            }
    81
    6.60M
          }
    82
    12.9M
          j <<= 6;
    83
    12.9M
        }
    84
    17.4M
      }
    85
    4.53M
      assert(i < 10);
    86
    21.9M
      for (; 4.53Mi >= 0; i--17.4M)
    87
    17.4M
      {
    88
    17.4M
        branch = breadcrumb[i];
    89
    17.4M
        int leaf = branch->terminal.off & 0x1;
    90
    17.4M
        if (!leaf)
    91
    15.9M
        {
    92
    15.9M
          ccv_cache_index_t* set = (ccv_cache_index_t*)(branch->branch.set - (branch->branch.set & 0x3));
    93
    15.9M
          uint32_t total = compute_bits(branch->branch.bitmap);
    94
    15.9M
          uint32_t min_age = (set[0].terminal.off & 0x1) ? CCV_GET_TERMINAL_AGE4.15M(set[0].terminal.type) : set[0].branch.age11.8M;
    95
    804M
          for (j = 1; j < total; j++788M)
    96
    788M
          {
    97
    788M
            uint32_t age = (set[j].terminal.off & 0x1) ? CCV_GET_TERMINAL_AGE74.3M(set[j].terminal.type) : set[j].branch.age714M;
    98
    788M
            if (age < min_age)
    99
    49.2M
              min_age = age;
    100
    788M
          }
    101
    15.9M
          branch->branch.age = min_age;
    102
    15.9M
        }
    103
    17.4M
      }
    104
    4.53M
    }
    105
    106
    static ccv_cache_index_t* _ccv_cache_seek(ccv_cache_index_t* branch, uint64_t sign, int* depth)
    107
    5.86M
    {
    108
    5.86M
      if (!bits_in_16bits_init)
    109
    1
        precomputed_16bits();
    110
    5.86M
      int i;
    111
    5.86M
      uint64_t j = 63;
    112
    23.0M
      for (i = 0; i < 10; i++17.1M)
    113
    23.0M
      {
    114
    23.0M
        int leaf = branch->terminal.off & 0x1;
    115
    23.0M
        int full = branch->terminal.off & 0x2;
    116
    23.0M
        if (leaf)
    117
    2.25M
        {
    118
    2.25M
          if (depth)
    119
    1.64M
            *depth = i;
    120
    2.25M
          return branch;
    121
    20.7M
        } else {
    122
    20.7M
          ccv_cache_index_t* set = (ccv_cache_index_t*)(branch->branch.set - (branch->branch.set & 0x3));
    123
    20.7M
          int dice = (sign & j) >> (i * 6);
    124
    20.7M
          if (full)
    125
    12.0M
          {
    126
    12.0M
            branch = set + dice;
    127
    12.0M
          } else {
    128
    8.74M
            uint64_t k = 1;
    129
    8.74M
            k = k << dice;
    130
    8.74M
            if (k & branch->branch.bitmap) {
    131
    5.12M
              uint64_t m = (k - 1) & branch->branch.bitmap;
    132
    5.12M
              branch = set + compute_bits(m);
    133
    5.12M
            } else {
    134
    3.61M
              if (depth)
    135
    3.42M
                *depth = i;
    136
    3.61M
              return branch;
    137
    3.61M
            }
    138
    8.74M
          }
    139
    17.1M
          j <<= 6;
    140
    17.1M
        }
    141
    23.0M
      }
    142
    0
      return 0;
    143
    5.86M
    }
    144
    145
    void* ccv_cache_get(ccv_cache_t* cache, uint64_t sign, uint8_t* type)
    146
    800k
    {
    147
    800k
      if (cache->rnum == 0)
    148
    0
        return 0;
    149
    800k
      ccv_cache_index_t* branch = _ccv_cache_seek(&cache->origin, sign, 0);
    150
    800k
      if (!branch)
    151
    0
        return 0;
    152
    800k
      int leaf = branch->terminal.off & 0x1;
    153
    800k
      if (!leaf)
    154
    188k
        return 0;
    155
    611k
      if (branch->terminal.sign != sign)
    156
    77.4k
        return 0;
    157
    533k
      if (type)
    158
    0
        *type = CCV_GET_CACHE_TYPE(branch->terminal.type);
    159
    533k
      return (void*)(branch->terminal.off - (branch->terminal.off & 0x3));
    160
    611k
    }
    161
    162
    // only call this function when the cache space is delpeted
    163
    static void _ccv_cache_lru(ccv_cache_t* cache)
    164
    679k
    {
    165
    679k
      ccv_cache_index_t* branch = &cache->origin;
    166
    679k
      int leaf = branch->terminal.off & 0x1;
    167
    679k
      if (leaf)
    168
    0
      {
    169
    0
        void* result = (void*)(branch->terminal.off - (branch->terminal.off & 0x3));
    170
    0
        uint8_t type = CCV_GET_CACHE_TYPE(branch->terminal.type);
    171
    0
        if (result != 0)
    172
    0
        {
    173
    0
          assert(type >= 0 && type < 16);
    174
    0
          cache->ffree[type](result);
    175
    0
        }
    176
    0
        cache->rnum = 0;
    177
    0
        cache->size = 0;
    178
    0
        return;
    179
    0
      }
    180
    679k
      uint32_t min_age = branch->branch.age;
    181
    679k
      int i, j;
    182
    3.30M
      for (i = 0; i < 10; i++2.62M)
    183
    3.30M
      {
    184
    3.30M
        ccv_cache_index_t* old_branch = branch;
    185
    3.30M
        int leaf = branch->terminal.off & 0x1;
    186
    3.30M
        if (leaf)
    187
    679k
        {
    188
    679k
          ccv_cache_delete(cache, branch->terminal.sign);
    189
    679k
          break;
    190
    2.62M
        } else {
    191
    2.62M
          ccv_cache_index_t* set = (ccv_cache_index_t*)(branch->branch.set - (branch->branch.set & 0x3));
    192
    2.62M
          uint32_t total = compute_bits(branch->branch.bitmap);
    193
    63.9M
          for (j = 0; j < total; j++61.3M)
    194
    63.9M
          {
    195
    63.9M
            uint32_t age = (set[j].terminal.off & 0x1) ? CCV_GET_TERMINAL_AGE6.86M(set[j].terminal.type) : set[j].branch.age57.1M;
    196
    63.9M
            assert(age >= min_age);
    197
    63.9M
            if (age == min_age)
    198
    2.62M
            {
    199
    2.62M
              branch = set + j;
    200
    2.62M
              break;
    201
    2.62M
            }
    202
    63.9M
          }
    203
    2.62M
          assert(old_branch != branch);
    204
    2.62M
        }
    205
    3.30M
      }
    206
    679k
      assert(i < 10);
    207
    679k
    }
    208
    209
    static void _ccv_cache_depleted(ccv_cache_t* cache, size_t size)
    210
    679k
    {
    211
    1.35M
      while (cache->size > size)
    212
    679k
        _ccv_cache_lru(cache);
    213
    679k
    }
    214
    215
    int ccv_cache_put(ccv_cache_t* cache, uint64_t sign, void* x, uint32_t size, uint8_t type)
    216
    5.06M
    {
    217
    5.06M
      assert(((uint64_t)x & 0x3) == 0);
    218
    5.06M
      if (size > cache->up)
    219
    0
        return -1;
    220
    5.06M
      if (size + cache->size > cache->up)
    221
    679k
        _ccv_cache_depleted(cache, cache->up - size);
    222
    5.06M
      if (cache->rnum == 0)
    223
    5
      {
    224
    5
        cache->age = 1;
    225
    5
        cache->origin.terminal.off = (uint64_t)x | 0x1;
    226
    5
        cache->origin.terminal.sign = sign;
    227
    5
        cache->origin.terminal.type = CCV_SET_TERMINAL_TYPE(type, cache->age, size);
    228
    5
        cache->size = size;
    229
    5
        cache->rnum = 1;
    230
    5
        return 0;
    231
    5
      }
    232
    5.06M
      ++cache->age;
    233
    5.06M
      int i, depth = -1;
    234
    5.06M
      ccv_cache_index_t* branch = _ccv_cache_seek(&cache->origin, sign, &depth);
    235
    5.06M
      if (!branch)
    236
    0
        return -1;
    237
    5.06M
      int leaf = branch->terminal.off & 0x1;
    238
    5.06M
      uint64_t on = 1;
    239
    5.06M
      assert(depth >= 0);
    240
    5.06M
      if (leaf)
    241
    1.64M
      {
    242
    1.64M
        if (sign == branch->terminal.sign)
    243
    356k
        {
    244
    356k
          cache->ffree[CCV_GET_CACHE_TYPE(branch->terminal.type)]((void*)(branch->terminal.off - (branch->terminal.off & 0x3)));
    245
    356k
          branch->terminal.off = (uint64_t)x | 0x1;
    246
    356k
          uint32_t old_size = CCV_GET_TERMINAL_SIZE(branch->terminal.type);
    247
    356k
          cache->size = cache->size + size - old_size;
    248
    356k
          branch->terminal.type = CCV_SET_TERMINAL_TYPE(type, cache->age, size);
    249
    356k
          _ccv_cache_aging(&cache->origin, sign);
    250
    356k
          return 1;
    251
    1.28M
        } else {
    252
    1.28M
          ccv_cache_index_t t = *branch;
    253
    1.28M
          uint32_t age = CCV_GET_TERMINAL_AGE(branch->terminal.type);
    254
    1.28M
          uint64_t j = 63;
    255
    1.28M
          j = j << (depth * 6);
    256
    1.28M
          int dice, udice;
    257
    1.28M
          assert(depth < 10);
    258
    1.30M
          for (i = depth; 1.28Mi < 10; i++20.5k)
    259
    1.30M
          {
    260
    1.30M
            dice = (t.terminal.sign & j) >> (i * 6);
    261
    1.30M
            udice = (sign & j) >> (i * 6);
    262
    1.30M
            if (dice == udice)
    263
    20.5k
            {
    264
    20.5k
              branch->branch.bitmap = on << dice;
    265
    20.5k
              ccv_cache_index_t* set = (ccv_cache_index_t*)ccmalloc(sizeof(ccv_cache_index_t));
    266
    20.5k
              assert(((uint64_t)set & 0x3) == 0);
    267
    20.5k
              branch->branch.set = (uint64_t)set;
    268
    20.5k
              branch->branch.age = age;
    269
    20.5k
              branch = set;
    270
    1.28M
            } else {
    271
    1.28M
              break;
    272
    1.28M
            }
    273
    20.5k
            j <<= 6;
    274
    20.5k
          }
    275
    1.28M
          branch->branch.bitmap = (on << dice) | (on << udice);
    276
    1.28M
          ccv_cache_index_t* set = (ccv_cache_index_t*)ccmalloc(sizeof(ccv_cache_index_t) * 2);
    277
    1.28M
          assert(((uint64_t)set & 0x3) == 0);
    278
    1.28M
          branch->branch.set = (uint64_t)set;
    279
    1.28M
          branch->branch.age = age;
    280
    1.28M
          int u = dice < udice;
    281
    1.28M
          set[u].terminal.sign = sign;
    282
    1.28M
          set[u].terminal.off = (uint64_t)x | 0x1;
    283
    1.28M
          set[u].terminal.type = CCV_SET_TERMINAL_TYPE(type, cache->age, size);
    284
    1.28M
          set[1 - u] = t;
    285
    1.28M
        }
    286
    3.42M
      } else {
    287
    3.42M
        uint64_t k = 1, j = 63;
    288
    3.42M
        k = k << ((sign & (j << (depth * 6))) >> (depth * 6));
    289
    3.42M
        uint64_t m = (k - 1) & branch->branch.bitmap;
    290
    3.42M
        uint32_t start = compute_bits(m);
    291
    3.42M
        uint32_t total = compute_bits(branch->branch.bitmap);
    292
    3.42M
        ccv_cache_index_t* set = (ccv_cache_index_t*)(branch->branch.set - (branch->branch.set & 0x3));
    293
    3.42M
        set = (ccv_cache_index_t*)ccrealloc(set, sizeof(ccv_cache_index_t) * (total + 1));
    294
    3.42M
        assert(((uint64_t)set & 0x3) == 0);
    295
    27.6M
        for (i = total; 3.42Mi > start; i--24.2M)
    296
    24.2M
          set[i] = set[i - 1];
    297
    3.42M
        set[start].terminal.off = (uint64_t)x | 0x1;
    298
    3.42M
        set[start].terminal.sign = sign;
    299
    3.42M
        set[start].terminal.type = CCV_SET_TERMINAL_TYPE(type, cache->age, size);
    300
    3.42M
        branch->branch.set = (uint64_t)set;
    301
    3.42M
        branch->branch.bitmap |= k;
    302
    3.42M
        if (total == 63)
    303
    4.28k
          branch->branch.set |= 0x2;
    304
    3.42M
      }
    305
    4.71M
      cache->rnum++;
    306
    4.71M
      cache->size += size;
    307
    4.71M
      return 0;
    308
    5.06M
    }
    309
    310
    static void _ccv_cache_cleanup(ccv_cache_index_t* branch)
    311
    1.13M
    {
    312
    1.13M
      int leaf = branch->terminal.off & 0x1;
    313
    1.13M
      if (!leaf)
    314
    1.13M
      {
    315
    1.13M
        int i;
    316
    1.13M
        uint64_t total = compute_bits(branch->branch.bitmap);
    317
    1.13M
        ccv_cache_index_t* set = (ccv_cache_index_t*)(branch->branch.set - (branch->branch.set & 0x3));
    318
    3.38M
        for (i = 0; i < total; i++2.25M)
    319
    2.25M
        {
    320
    2.25M
          if (!(set[i].terminal.off & 0x1))
    321
    17.8k
            _ccv_cache_cleanup(set + i);
    322
    2.25M
        }
    323
    1.13M
        ccfree(set);
    324
    1.13M
      }
    325
    1.13M
    }
    326
    327
    static void _ccv_cache_cleanup_and_free(ccv_cache_index_t* branch, ccv_cache_index_free_f ffree[])
    328
    704k
    {
    329
    704k
      int leaf = branch->terminal.off & 0x1;
    330
    704k
      if (!leaf)
    331
    171k
      {
    332
    171k
        int i;
    333
    171k
        uint64_t total = compute_bits(branch->branch.bitmap);
    334
    171k
        ccv_cache_index_t* set = (ccv_cache_index_t*)(branch->branch.set - (branch->branch.set & 0x3));
    335
    875k
        for (i = 0; i < total; i++704k)
    336
    704k
          _ccv_cache_cleanup_and_free(set + i, ffree);
    337
    171k
        ccfree(set);
    338
    533k
      } else {
    339
    533k
        assert(CCV_GET_CACHE_TYPE(branch->terminal.type) >= 0 && CCV_GET_CACHE_TYPE(branch->terminal.type) < 16);
    340
    533k
        ffree[CCV_GET_CACHE_TYPE(branch->terminal.type)]((void*)(branch->terminal.off - (branch->terminal.off & 0x3)));
    341
    533k
      }
    342
    704k
    }
    343
    344
    void* ccv_cache_out(ccv_cache_t* cache, uint64_t sign, uint8_t* type)
    345
    4.75M
    {
    346
    4.75M
      if (!bits_in_16bits_init)
    347
    0
        precomputed_16bits();
    348
    4.75M
      if (cache->rnum == 0)
    349
    487k
        return 0;
    350
    4.26M
      int i, found = 0, depth = -1;
    351
    4.26M
      ccv_cache_index_t* parent = 0;
    352
    4.26M
      ccv_cache_index_t* uncle = &cache->origin;
    353
    4.26M
      ccv_cache_index_t* branch = &cache->origin;
    354
    4.26M
      uint64_t j = 63;
    355
    20.2M
      for (i = 0; i < 10; i++15.9M)
    356
    20.2M
      {
    357
    20.2M
        int leaf = branch->terminal.off & 0x1;
    358
    20.2M
        int full = branch->terminal.off & 0x2;
    359
    20.2M
        if (leaf)
    360
    4.20M
        {
    361
    4.20M
          found = 1;
    362
    4.20M
          break;
    363
    4.20M
        }
    364
    16.0M
        if (parent != 0 && compute_bits(parent->branch.bitmap) > 111.7M)
    365
    11.7M
          uncle = branch;
    366
    16.0M
        parent = branch;
    367
    16.0M
        depth = i;
    368
    16.0M
        ccv_cache_index_t* set = (ccv_cache_index_t*)(branch->branch.set - (branch->branch.set & 0x3));
    369
    16.0M
        int dice = (sign & j) >> (i * 6);
    370
    16.0M
        if (full)
    371
    8.84M
        {
    372
    8.84M
          branch = set + dice;
    373
    8.84M
        } else {
    374
    7.20M
          uint64_t k = 1;
    375
    7.20M
          k = k << dice;
    376
    7.20M
          if (k & branch->branch.bitmap)
    377
    7.14M
          {
    378
    7.14M
            uint64_t m = (k - 1) & branch->branch.bitmap;
    379
    7.14M
            branch = set + compute_bits(m);
    380
    7.14M
          } else {
    381
    62.9k
            return 0;
    382
    62.9k
          }
    383
    7.20M
        }
    384
    15.9M
        j <<= 6;
    385
    15.9M
      }
    386
    4.20M
      if (!found)
    387
    0
        return 0;
    388
    4.20M
      int leaf = branch->terminal.off & 0x1;
    389
    4.20M
      if (!leaf)
    390
    0
        return 0;
    391
    4.20M
      if (branch->terminal.sign != sign)
    392
    25.6k
        return 0;
    393
    4.17M
      void* result = (void*)(branch->terminal.off - (branch->terminal.off & 0x3));
    394
    4.17M
      if (type)
    395
    4.17M
        *type = CCV_GET_CACHE_TYPE(branch->terminal.type);
    396
    4.17M
      uint32_t size = CCV_GET_TERMINAL_SIZE(branch->terminal.type);
    397
    4.17M
      if (branch != &cache->origin)
    398
    4.17M
      {
    399
    4.17M
        uint64_t k = 1, j = 63;
    400
    4.17M
        int dice = (sign & (j << (depth * 6))) >> (depth * 6);
    401
    4.17M
        k = k << dice;
    402
    4.17M
        uint64_t m = (k - 1) & parent->branch.bitmap;
    403
    4.17M
        uint32_t start = compute_bits(m);
    404
    4.17M
        uint32_t total = compute_bits(parent->branch.bitmap);
    405
    4.17M
        assert(total > 1);
    406
    4.17M
        ccv_cache_index_t* set = (ccv_cache_index_t*)(parent->branch.set - (parent->branch.set & 0x3));
    407
    4.17M
        if (total > 2 || (1.12Mtotal == 21.12M && !(set[1 - start].terminal.off & 0x1)1.12M))
    408
    3.06M
        {
    409
    3.06M
          parent->branch.bitmap &= ~k;
    410
    23.9M
          for (i = start + 1; i < total; i++20.8M)
    411
    20.8M
            set[i - 1] = set[i];
    412
    3.06M
          set = (ccv_cache_index_t*)ccrealloc(set, sizeof(ccv_cache_index_t) * (total - 1));
    413
    3.06M
          parent->branch.set = (uint64_t)set;
    414
    3.06M
        } else {
    415
    1.11M
          ccv_cache_index_t t = set[1 - start];
    416
    1.11M
          _ccv_cache_cleanup(uncle);
    417
    1.11M
          *uncle = t;
    418
    1.11M
        }
    419
    4.17M
        _ccv_cache_aging(&cache->origin, sign);
    420
    4.17M
      } else {
    421
        // if I only have one item, reset age to 1
    422
    4
        cache->age = 1;
    423
    4
      }
    424
    4.17M
      cache->rnum--;
    425
    4.17M
      cache->size -= size;
    426
    4.17M
      return result;
    427
    4.17M
    }
    428
    429
    int ccv_cache_delete(ccv_cache_t* cache, uint64_t sign)
    430
    1.74M
    {
    431
    1.74M
      uint8_t type = 0;
    432
    1.74M
      void* result = ccv_cache_out(cache, sign, &type);
    433
    1.74M
      if (result != 0)
    434
    1.65M
      {
    435
    1.65M
        assert(type >= 0 && type < 16);
    436
    1.65M
        cache->ffree[type](result);
    437
    1.65M
        return 0;
    438
    1.65M
      }
    439
    88.6k
      return -1;
    440
    1.74M
    }
    441
    442
    void ccv_cache_cleanup(ccv_cache_t* cache)
    443
    4
    {
    444
    4
      if (cache->rnum > 0)
    445
    1
      {
    446
    1
        _ccv_cache_cleanup_and_free(&cache->origin, cache->ffree);
    447
    1
        cache->size = 0;
    448
    1
        cache->age = 0;
    449
    1
        cache->rnum = 0;
    450
    1
        memset(&cache->origin, 0, sizeof(ccv_cache_index_t));
    451
    1
      }
    452
    4
    }
    453
    454
    void ccv_cache_close(ccv_cache_t* cache)
    455
    4
    {
    456
      // for radix-tree based cache, close/cleanup are the same (it is not the same for cuckoo based one,
    457
      // because for cuckoo based one, it will free up space in close whereas only cleanup space in cleanup
    458
    4
      ccv_cache_cleanup(cache);
    459
    4
    }