/* Returns whether the tile should be written (and freed if no denoising is used) instead of updating. */ bool TileManager::finish_tile(int index, bool &delete_tile) { delete_tile = false; switch(state.tiles[index].state) { case Tile::RENDER: { if(!schedule_denoising) { state.tiles[index].state = Tile::DONE; delete_tile = true; return true; } state.tiles[index].state = Tile::RENDERED; /* For each neighbor and the tile itself, check whether all of its neighbors have been rendered. If yes, it can be denoised. */ for(int neighbor = 0; neighbor < 9; neighbor++) { int nindex = get_neighbor_index(index, neighbor); if(check_neighbor_state(nindex, Tile::RENDERED)) { state.tiles[nindex].state = Tile::DENOISE; state.denoising_tiles[state.tiles[nindex].device].push_back(nindex); } } return false; } case Tile::DENOISE: { state.tiles[index].state = Tile::DENOISED; /* For each neighbor and the tile itself, check whether all of its neighbors have been denoised. If yes, it can be freed. */ for(int neighbor = 0; neighbor < 9; neighbor++) { int nindex = get_neighbor_index(index, neighbor); if(check_neighbor_state(nindex, Tile::DENOISED)) { state.tiles[nindex].state = Tile::DONE; /* It can happen that the tile just finished denoising and already can be freed here. * However, in that case it still has to be written before deleting, so we can't delete it yet. */ if(neighbor == 8) { delete_tile = true; } else { delete state.tiles[nindex].buffers; state.tiles[nindex].buffers = NULL; } } } return true; } default: assert(false); return true; } }
// Deletes an entry from the B+ tree. node * delete_entry( node * root, node * n, int key, void * pointer ) { int min_keys; node * neighbor; int neighbor_index; int k_prime_index, k_prime; int capacity; // Remove key and pointer from node. n = remove_entry_from_node(n, key, pointer); /* Case: deletion from the root. */ if (n == root) return adjust_root(root); // Case: deletion from a node below the root. // Determine minimum allowable size of node, to be preserved after deletion. min_keys = n->is_leaf ? cut(order - 1) : cut(order) - 1; // Case: node stays at or above minimum. if (n->num_keys >= min_keys) return root; /* Find the appropriate neighbor node with which * to merge. * Also find the key (k_prime) in the parent * between the pointer to node n and the pointer * to the neighbor. */ neighbor_index = get_neighbor_index( n ); k_prime_index = neighbor_index == -1 ? 0 : neighbor_index; k_prime = n->parent->keys[k_prime_index]; neighbor = neighbor_index == -1 ? n->parent->pointers[1] : n->parent->pointers[neighbor_index]; capacity = n->is_leaf ? order : order - 1; /* mergence. */ if (neighbor->num_keys + n->num_keys < capacity) return merge_nodes(root, n, neighbor, neighbor_index, k_prime); /* Redistribution. */ else return redistribute_nodes(root, n, neighbor, neighbor_index, k_prime_index, k_prime); }
/* Checks whether all neighbors of a tile (as well as the tile itself) are at least at state min_state. */ bool TileManager::check_neighbor_state(int index, Tile::State min_state) { if(index < 0 || state.tiles[index].state < min_state) { return false; } for(int neighbor = 0; neighbor < 9; neighbor++) { int nindex = get_neighbor_index(index, neighbor); /* Out-of-bounds tiles don't matter. */ if(nindex >= 0 && state.tiles[nindex].state < min_state) { return false; } } return true; }