Coverage Report

Created: 2024-08-19 11:27

/home/liu/actions-runner/_work/ccv/ccv/test/unit/memory.tests.c
Line
Count
Source (jump to first uncovered line)
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, 0
N0
- 1 - i);
40
800k
  }
41
800k
  
for (i = 0; 1
i < 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*)720k
ccv_array_get720k
(array, 1) &&
166
751k
      
~i == *(int*)720k
ccv_array_get720k
(array, 2) &&
167
751k
      
-i == *(int*)720k
ccv_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"