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 "spdk/blobfs.h" 9 : : #include "cache_tree.h" 10 : : 11 : : #include "spdk/queue.h" 12 : : #include "spdk/assert.h" 13 : : #include "spdk/env.h" 14 : : #include "spdk/log.h" 15 : : 16 : : struct cache_buffer * 17 : 100751231 : tree_find_buffer(struct cache_tree *tree, uint64_t offset) 18 : : { 19 : : uint64_t index; 20 : : 21 [ + + ]: 201691866 : while (tree != NULL) { 22 [ - + - + ]: 197969504 : index = offset / CACHE_TREE_LEVEL_SIZE(tree->level); 23 [ + + ]: 197969504 : if (index >= CACHE_TREE_WIDTH) { 24 : 71705 : return NULL; 25 : : } 26 [ + + ]: 197897799 : if (tree->level == 0) { 27 : 96957164 : return tree->u.buffer[index]; 28 : : } else { 29 [ - + ]: 100940635 : offset &= CACHE_TREE_LEVEL_MASK(tree->level); 30 : 100940635 : tree = tree->u.tree[index]; 31 : : } 32 : : } 33 : : 34 : 3722362 : return NULL; 35 : : } 36 : : 37 : : struct cache_buffer * 38 : 36404485 : tree_find_filled_buffer(struct cache_tree *tree, uint64_t offset) 39 : : { 40 : : struct cache_buffer *buf; 41 : : 42 : 36404485 : buf = tree_find_buffer(tree, offset); 43 [ + + + + ]: 36404485 : if (buf != NULL && buf->bytes_filled > 0) { 44 : 32244824 : return buf; 45 : : } else { 46 : 4159661 : return NULL; 47 : : } 48 : : } 49 : : 50 : : struct cache_tree * 51 : 1336881 : tree_insert_buffer(struct cache_tree *root, struct cache_buffer *buffer) 52 : : { 53 : : struct cache_tree *tree; 54 : : uint64_t index, offset; 55 : : 56 : 1336881 : offset = buffer->offset; 57 [ + + + + ]: 1343336 : while (offset >= CACHE_TREE_LEVEL_SIZE(root->level + 1)) { 58 [ + + ]: 6455 : if (root->present_mask != 0) { 59 : 3085 : tree = calloc(1, sizeof(*tree)); 60 [ - + ]: 3085 : assert(tree != NULL); 61 : 3085 : tree->level = root->level + 1; 62 : 3085 : tree->u.tree[0] = root; 63 : 3085 : root = tree; 64 : 3085 : root->present_mask = 0x1ULL; 65 : : } else { 66 : 3370 : root->level++; 67 : : } 68 : : } 69 : : 70 : 1336881 : tree = root; 71 [ + + ]: 2484853 : while (tree->level > 0) { 72 [ - + - + ]: 1147972 : index = offset / CACHE_TREE_LEVEL_SIZE(tree->level); 73 [ - + ]: 1147972 : assert(index < CACHE_TREE_WIDTH); 74 [ - + ]: 1147972 : offset &= CACHE_TREE_LEVEL_MASK(tree->level); 75 [ + + ]: 1147972 : if (tree->u.tree[index] == NULL) { 76 : 25479 : tree->u.tree[index] = calloc(1, sizeof(*tree)); 77 [ - + ]: 25479 : assert(tree->u.tree[index] != NULL); 78 : 25479 : tree->u.tree[index]->level = tree->level - 1; 79 [ - + ]: 25479 : tree->present_mask |= (1ULL << index); 80 : : } 81 : 1147972 : tree = tree->u.tree[index]; 82 : : } 83 : : 84 : 1336881 : index = offset / CACHE_BUFFER_SIZE; 85 [ - + ]: 1336881 : assert(index < CACHE_TREE_WIDTH); 86 [ - + ]: 1336881 : assert(tree->u.buffer[index] == NULL); 87 : 1336881 : tree->u.buffer[index] = buffer; 88 [ - + ]: 1336881 : tree->present_mask |= (1ULL << index); 89 : 1336881 : return root; 90 : : } 91 : : 92 : : void 93 : 1005586 : tree_remove_buffer(struct cache_tree *tree, struct cache_buffer *buffer) 94 : : { 95 : : struct cache_tree *child; 96 : : uint64_t index; 97 : : 98 [ - + ]: 1005586 : index = CACHE_TREE_INDEX(tree->level, buffer->offset); 99 : : 100 [ + + ]: 1005586 : if (tree->level == 0) { 101 [ - + ]: 500526 : assert(tree->u.buffer[index] != NULL); 102 [ - + ]: 500526 : assert(buffer == tree->u.buffer[index]); 103 [ - + ]: 500526 : tree->present_mask &= ~(1ULL << index); 104 : 500526 : tree->u.buffer[index] = NULL; 105 : 500526 : cache_buffer_free(buffer); 106 : 500526 : return; 107 : : } 108 : : 109 : 505060 : child = tree->u.tree[index]; 110 [ - + ]: 505060 : assert(child != NULL); 111 : 505060 : tree_remove_buffer(child, buffer); 112 [ + + ]: 505060 : if (child->present_mask == 0) { 113 [ - + ]: 6903 : tree->present_mask &= ~(1ULL << index); 114 : 6903 : tree->u.tree[index] = NULL; 115 : 6903 : free(child); 116 : : } 117 : : } 118 : : 119 : : void 120 : 32173 : tree_free_buffers(struct cache_tree *tree) 121 : : { 122 : : struct cache_buffer *buffer; 123 : : struct cache_tree *child; 124 : : uint32_t i; 125 : : 126 [ - + ]: 32173 : if (tree->present_mask == 0) { 127 : 0 : return; 128 : : } 129 : : 130 [ + + ]: 32173 : if (tree->level == 0) { 131 [ + + ]: 1422070 : for (i = 0; i < CACHE_TREE_WIDTH; i++) { 132 : 1400192 : buffer = tree->u.buffer[i]; 133 [ + + + + : 1400192 : if (buffer != NULL && buffer->in_progress == false && + + ] 134 [ + - ]: 836367 : buffer->bytes_filled == buffer->bytes_flushed) { 135 : 836367 : cache_buffer_free(buffer); 136 : 836367 : tree->u.buffer[i] = NULL; 137 [ - + ]: 836367 : tree->present_mask &= ~(1ULL << i); 138 : : } 139 : : } 140 : : } else { 141 [ + + ]: 669175 : for (i = 0; i < CACHE_TREE_WIDTH; i++) { 142 : 658880 : child = tree->u.tree[i]; 143 [ + + ]: 658880 : if (child != NULL) { 144 : 21686 : tree_free_buffers(child); 145 [ + + ]: 21686 : if (child->present_mask == 0) { 146 : 21673 : free(child); 147 : 21673 : tree->u.tree[i] = NULL; 148 [ - + ]: 21673 : tree->present_mask &= ~(1ULL << i); 149 : : } 150 : : } 151 : : } 152 : : } 153 : : }