Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2017 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/stdinc.h"
7 : :
8 : : #include "cache_tree.h"
9 : :
10 : : #include "spdk/assert.h"
11 : :
12 : : struct cache_buffer *
13 : 81275330 : tree_find_buffer(struct cache_tree *tree, uint64_t offset)
14 : : {
15 : : uint64_t index;
16 : :
17 [ + + ]: 165911583 : while (tree != NULL) {
18 [ - + - + : 162054459 : index = offset / CACHE_TREE_LEVEL_SIZE(tree->level);
# # # # #
# # # ]
19 [ + + # # ]: 162054459 : if (index >= CACHE_TREE_WIDTH) {
20 : 19528 : return NULL;
21 : : }
22 [ + + # # : 162034931 : if (tree->level == 0) {
# # ]
23 [ # # # # : 77398678 : return tree->u.buffer[index];
# # # # #
# ]
24 : : } else {
25 [ - + # # : 84636253 : offset &= CACHE_TREE_LEVEL_MASK(tree->level);
# # # # #
# ]
26 [ # # # # : 84636253 : tree = tree->u.tree[index];
# # # # ]
27 : : }
28 : : }
29 : :
30 : 3857124 : return NULL;
31 : 0 : }
32 : :
33 : : struct cache_buffer *
34 : 30029086 : tree_find_filled_buffer(struct cache_tree *tree, uint64_t offset)
35 : : {
36 : : struct cache_buffer *buf;
37 : :
38 : 30029086 : buf = tree_find_buffer(tree, offset);
39 [ + + + + : 30029086 : if (buf != NULL && buf->bytes_filled > 0) {
# # # # ]
40 : 25951391 : return buf;
41 : : } else {
42 : 4077695 : return NULL;
43 : : }
44 : 0 : }
45 : :
46 : : struct cache_tree *
47 : 1153662 : tree_insert_buffer(struct cache_tree *root, struct cache_buffer *buffer)
48 : : {
49 : : struct cache_tree *tree;
50 : : uint64_t index, offset;
51 : :
52 [ # # # # ]: 1153662 : offset = buffer->offset;
53 [ + + + + : 1159266 : while (offset >= CACHE_TREE_LEVEL_SIZE(root->level + 1)) {
# # # # #
# # # #
# ]
54 [ + + # # : 5604 : if (root->present_mask != 0) {
# # ]
55 : 2594 : tree = calloc(1, sizeof(*tree));
56 [ - + # # ]: 2594 : assert(tree != NULL);
57 [ # # # # : 2594 : tree->level = root->level + 1;
# # # # #
# ]
58 [ # # # # : 2594 : tree->u.tree[0] = root;
# # # # ]
59 : 2594 : root = tree;
60 [ # # # # ]: 2594 : root->present_mask = 0x1ULL;
61 : 0 : } else {
62 [ # # ]: 3010 : root->level++;
63 : : }
64 : : }
65 : :
66 : 1153662 : tree = root;
67 [ + + # # : 2170791 : while (tree->level > 0) {
# # ]
68 [ - + - + : 1017129 : index = offset / CACHE_TREE_LEVEL_SIZE(tree->level);
# # # # #
# # # ]
69 [ - + # # : 1017129 : assert(index < CACHE_TREE_WIDTH);
# # ]
70 [ - + # # : 1017129 : offset &= CACHE_TREE_LEVEL_MASK(tree->level);
# # # # #
# ]
71 [ + + # # : 1017129 : if (tree->u.tree[index] == NULL) {
# # # # #
# ]
72 [ # # # # : 21546 : tree->u.tree[index] = calloc(1, sizeof(*tree));
# # # # ]
73 [ - + # # : 21546 : assert(tree->u.tree[index] != NULL);
# # # # #
# # # ]
74 [ # # # # : 21546 : tree->u.tree[index]->level = tree->level - 1;
# # # # #
# # # # #
# # # # ]
75 [ - + # # : 21546 : tree->present_mask |= (1ULL << index);
# # ]
76 : 0 : }
77 [ # # # # : 1017129 : tree = tree->u.tree[index];
# # # # ]
78 : : }
79 : :
80 [ # # # # ]: 1153662 : index = offset / CACHE_BUFFER_SIZE;
81 [ - + # # : 1153662 : assert(index < CACHE_TREE_WIDTH);
# # ]
82 [ - + # # : 1153662 : assert(tree->u.buffer[index] == NULL);
# # # # #
# # # #
# ]
83 [ # # # # : 1153662 : tree->u.buffer[index] = buffer;
# # # # #
# ]
84 [ - + # # : 1153662 : tree->present_mask |= (1ULL << index);
# # ]
85 : 1153662 : return root;
86 : : }
87 : :
88 : : void
89 : 828301 : tree_remove_buffer(struct cache_tree *tree, struct cache_buffer *buffer)
90 : : {
91 : : struct cache_tree *child;
92 : : uint64_t index;
93 : :
94 [ - + # # : 828301 : index = CACHE_TREE_INDEX(tree->level, buffer->offset);
# # # # #
# # # # #
# # ]
95 : :
96 [ + + # # : 828301 : if (tree->level == 0) {
# # ]
97 [ - + # # : 403636 : assert(tree->u.buffer[index] != NULL);
# # # # #
# # # #
# ]
98 [ - + # # : 403636 : assert(buffer == tree->u.buffer[index]);
# # # # #
# # # #
# ]
99 [ - + # # : 403636 : tree->present_mask &= ~(1ULL << index);
# # ]
100 [ # # # # : 403636 : tree->u.buffer[index] = NULL;
# # # # #
# ]
101 : 403636 : cache_buffer_free(buffer);
102 : 403636 : return;
103 : : }
104 : :
105 [ # # # # : 424665 : child = tree->u.tree[index];
# # # # ]
106 [ - + # # ]: 424665 : assert(child != NULL);
107 : 424665 : tree_remove_buffer(child, buffer);
108 [ + + # # : 424665 : if (child->present_mask == 0) {
# # ]
109 [ - + # # : 5749 : tree->present_mask &= ~(1ULL << index);
# # ]
110 [ # # # # : 5749 : tree->u.tree[index] = NULL;
# # # # ]
111 : 5749 : free(child);
112 : 0 : }
113 : 0 : }
114 : :
115 : : void
116 : 26816 : tree_free_buffers(struct cache_tree *tree)
117 : : {
118 : : struct cache_buffer *buffer;
119 : : struct cache_tree *child;
120 : : uint32_t i;
121 : :
122 [ - + # # : 26816 : if (tree->present_mask == 0) {
# # ]
123 : 0 : return;
124 : : }
125 : :
126 [ + + # # : 26816 : if (tree->level == 0) {
# # ]
127 [ + + # # ]: 1202435 : for (i = 0; i < CACHE_TREE_WIDTH; i++) {
128 [ # # # # : 1183936 : buffer = tree->u.buffer[i];
# # # # #
# ]
129 [ + + + + : 1183936 : if (buffer != NULL && buffer->in_progress == false &&
+ + # # #
# # # ]
130 [ + - # # : 750032 : buffer->bytes_filled == buffer->bytes_flushed) {
# # # # ]
131 : 750032 : cache_buffer_free(buffer);
132 [ # # # # : 750032 : tree->u.buffer[i] = NULL;
# # # # #
# ]
133 [ - + # # : 750032 : tree->present_mask &= ~(1ULL << i);
# # ]
134 : 0 : }
135 : 0 : }
136 : 0 : } else {
137 [ + + # # ]: 540605 : for (i = 0; i < CACHE_TREE_WIDTH; i++) {
138 [ # # # # : 532288 : child = tree->u.tree[i];
# # # # ]
139 [ + + ]: 532288 : if (child != NULL) {
140 : 18535 : tree_free_buffers(child);
141 [ + + # # : 18535 : if (child->present_mask == 0) {
# # ]
142 : 18397 : free(child);
143 [ # # # # : 18397 : tree->u.tree[i] = NULL;
# # # # ]
144 [ - + # # : 18397 : tree->present_mask &= ~(1ULL << i);
# # ]
145 : 0 : }
146 : 0 : }
147 : 0 : }
148 : : }
149 : 0 : }
|