## Coverage Report

#### Created: 2026-05-04 15:30

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

    /home/liu/actions-runner/_work/ccv/ccv/test/unit/memory.tests.c

    Line
    Count
    Source
    1
    #include "ccv.h"
    2
    #include "ccv_internal.h"
    3
    #include "case.h"
    4
    5
    uint64_t uniqid()
    6
    800k
    {
    7
    800k
      union {
    8
    800k
        uint64_t u;
    9
    800k
        uint8_t chr[8];
    10
    800k
      } sign;
    11
    800k
      int i;
    12
    7.20M
      for (i = 0; i < 8; i++6.40M)
    13
    6.40M
        sign.chr[i] = rand() & 0xff;
    14
    800k
      return sign.u;
    15
    800k
    }
    16
    17
    8.65M
    #define N (800000)
    18
    19
    TEST_CASE("random cache put/delete/get")
    20
    1
    {
    21
    1
      ccv_cache_t cache;
    22
    1
      ccv_cache_init(&cache, N, 1, ccfree);
    23
    1
      uint64_t* sigs = ccmalloc(sizeof(uint64_t) * N);
    24
    1
      void** mems = ccmalloc(sizeof(void*) * N);
    25
    1
      int i;
    26
    800k
      for (i = 0; i < N; i++800k)
    27
    800k
      {
    28
    800k
        sigs[i] = uniqid();
    29
    800k
        mems[i] = ccmalloc(1);
    30
    800k
        ccv_cache_put(&cache, sigs[i], mems[i], 1, 0);
    31
    800k
        REQUIRE_EQ(i + 1, cache.size, "at %d should has cache size %d", i, i);
    32
    800k
      }
    33
    1
      uint8_t deleted[N];
    34
    800k
      for (i = 0; i < N; i++800k)
    35
    800k
      {
    36
    800k
        deleted[i] = 1;
    37
    800k
        if (deleted[i])
    38
    800k
          ccv_cache_delete(&cache, sigs[i]);
    39
    800k
        REQUIRE_EQ(N - 1 - i, cache.size, "at %d should has cache size %d", i, 0N0 - 1 - i);
    40
    800k
      }
    41
    800k
      for (i = 0; 1i < N; i++800k)
    42
    800k
      {
    43
    800k
        deleted[i] = (rand() % 3 == 0);
    44
    800k
        if (!deleted[i])
    45
    534k
        {
    46
    534k
          mems[i] = ccmalloc(1);
    47
    534k
          ccv_cache_put(&cache, sigs[i], mems[i], 1, 0);
    48
    534k
        }
    49
    800k
      }
    50
    800k
      for (i = 0; i < N; i++800k)
    51
    800k
      {
    52
    800k
        deleted[i] = (rand() % 3 == 0);
    53
    800k
        if (deleted[i])
    54
    266k
          ccv_cache_delete(&cache, sigs[i]);
    55
    533k
        else {
    56
    533k
          mems[i] = ccmalloc(1);
    57
    533k
          ccv_cache_put(&cache, sigs[i], mems[i], 1, 0);
    58
    533k
        }
    59
    800k
      }
    60
    800k
      for (i = 0; i < N; i++800k)
    61
    800k
      {
    62
    800k
        void* x = ccv_cache_get(&cache, sigs[i], 0);
    63
    800k
        if (!deleted[i] && x533k) // x may be pull off the cache
    64
    533k
        {
    65
    533k
          REQUIRE_EQ((uint64_t)mems[i], (uint64_t)x, "value at %d should be consistent", i);
    66
    533k
        } else
    67
    800k
          REQUIRE_EQ266k(0, (uint64_t)x, "at %d should not exist", i);
    68
    800k
      }
    69
    1
      ccv_cache_close(&cache);
    70
    1
      ccfree(mems);
    71
    1
      ccfree(sigs);
    72
    1
    }
    73
    74
    TEST_CASE("garbage collector 95\% hit rate")
    75
    1
    {
    76
    1
      int i;
    77
      // deliberately let only cache size fits 90% of data
    78
    1
      ccv_enable_cache(ccv_compute_dense_matrix_size(1, 1, CCV_32S | CCV_C1) * N * 9 / 10);
    79
    800k
      for (i = 0; i < N; i++800k)
    80
    800k
      {
    81
    800k
        ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32S | CCV_C1, 0, 0);
    82
    800k
        dmt->data.i32[0] = i;
    83
    800k
        dmt->sig = ccv_cache_generate_signature((const char*)&i, 4, CCV_EOF_SIGN);
    84
    800k
        dmt->type |= CCV_REUSABLE;
    85
    800k
        ccv_matrix_free(dmt);
    86
    800k
      }
    87
    1
      int percent = 0, total = 0;
    88
    752k
      for (i = N1 - 1; i > N * 6 / 100; i--751k)
    89
    751k
      {
    90
    751k
        uint64_t sig = ccv_cache_generate_signature((const char*)&i, 4, CCV_EOF_SIGN);
    91
    751k
        ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32S | CCV_C1, 0, sig);
    92
    751k
        if (i == dmt->data.i32[0])
    93
    720k
          ++percent;
    94
    751k
        ++total;
    95
    751k
        ccv_matrix_free_immediately(dmt);
    96
    751k
      }
    97
    1
      REQUIRE((double)percent / (double)total > 0.95, "the cache hit (%lf) should be greater than 95%%", (double)percent / (double)total);
    98
    1
      ccv_disable_cache();
    99
    1
    }
    100
    101
    TEST_CASE("garbage collector 47\% hit rate")
    102
    1
    {
    103
    1
      int i;
    104
      // deliberately let only cache size fits 45% of data
    105
    1
      ccv_enable_cache((size_t)((int64_t)ccv_compute_dense_matrix_size(1, 1, CCV_32S | CCV_C1) * N * 45 / 100));
    106
    800k
      for (i = 0; i < N; i++800k)
    107
    800k
      {
    108
    800k
        ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32S | CCV_C1, 0, 0);
    109
    800k
        dmt->data.i32[0] = i;
    110
    800k
        dmt->sig = ccv_cache_generate_signature((const char*)&i, 4, CCV_EOF_SIGN);
    111
    800k
        dmt->type |= CCV_REUSABLE;
    112
    800k
        ccv_matrix_free(dmt);
    113
    800k
      }
    114
    1
      int percent = 0, total = 0;
    115
    752k
      for (i = N1 - 1; i > N * 6 / 100; i--751k)
    116
    751k
      {
    117
    751k
        uint64_t sig = ccv_cache_generate_signature((const char*)&i, 4, CCV_EOF_SIGN);
    118
    751k
        ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32S | CCV_C1, 0, sig);
    119
    751k
        if (i == dmt->data.i32[0])
    120
    360k
          ++percent;
    121
    751k
        ++total;
    122
    751k
        ccv_matrix_free_immediately(dmt);
    123
    751k
      }
    124
    1
      REQUIRE((double)percent / (double)total > 0.47, "the cache hit (%lf) should be greater than 47%%", (double)percent / (double)total);
    125
    1
      ccv_disable_cache();
    126
    1
    }
    127
    128
    TEST_CASE("multi-type garbage collector 92\% hit rate")
    129
    1
    {
    130
    1
      int i;
    131
    1
      ccv_enable_cache((ccv_compute_dense_matrix_size(1, 1, CCV_32S | CCV_C1) + (sizeof(ccv_array_t) + 4 * 4)) * N * 9 / 10);
    132
    800k
      for (i = 0; i < N; i++800k)
    133
    800k
      {
    134
    800k
        ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32S | CCV_C1, 0, 0);
    135
    800k
        dmt->data.i32[0] = i;
    136
    800k
        dmt->sig = ccv_cache_generate_signature((const char*)&i, 4, CCV_EOF_SIGN);
    137
    800k
        dmt->type |= CCV_REUSABLE;
    138
    800k
        ccv_matrix_free(dmt);
    139
    800k
        ccv_array_t* array = ccv_array_new(4, 4, 0);
    140
    800k
        int j = i;
    141
    800k
        ccv_array_push(array, &j);
    142
    800k
        j = 0;
    143
    800k
        ccv_array_push(array, &j);
    144
    800k
        j = ~i;
    145
    800k
        ccv_array_push(array, &j);
    146
    800k
        j = -i;
    147
    800k
        ccv_array_push(array, &j);
    148
    800k
        array->sig = ccv_cache_generate_signature((const char*)&j, 4, CCV_EOF_SIGN);
    149
    800k
        array->type |= CCV_REUSABLE;
    150
    800k
        ccv_array_free(array);
    151
    800k
      }
    152
    1
      int percent = 0, total = 0;
    153
    752k
      for (i = N1 - 1; i > N * 6 / 100; i--751k)
    154
    751k
      {
    155
    751k
        uint64_t sig = ccv_cache_generate_signature((const char*)&i, 4, CCV_EOF_SIGN);
    156
    751k
        ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32S | CCV_C1, 0, sig);
    157
    751k
        if (i == dmt->data.i32[0])
    158
    720k
          ++percent;
    159
    751k
        ++total;
    160
    751k
        ccv_matrix_free_immediately(dmt);
    161
    751k
        int j = -i;
    162
    751k
        sig = ccv_cache_generate_signature((const char*)&j, 4, CCV_EOF_SIGN);
    163
    751k
        ccv_array_t* array = ccv_array_new(4, 4, sig);
    164
    751k
        if (i == *(int*)ccv_array_get(array, 0) &&
    165
    751k
          0 == *(int*)720kccv_array_get720k(array, 1) &&
    166
    751k
          ~i == *(int*)720kccv_array_get720k(array, 2) &&
    167
    751k
          -i == *(int*)720kccv_array_get720k(array, 3))
    168
    720k
          ++percent;
    169
    751k
        ++total;
    170
    751k
        ccv_array_free_immediately(array);
    171
    751k
      }
    172
    1
      REQUIRE((double)percent / (double)total > 0.92, "the cache hit (%lf) should be greater than 92%%", (double)percent / (double)total);
    173
    1
      ccv_disable_cache();
    174
    1
    }
    175
    176
    #include "case_main.h"