/** * @brief Initializes the Disk Cache. * * When this is finished, all data is on disk, and the in-RAM cache * is empty. * * @param element_count The number of data elements. * @param cache_size_ The max number of data blocks to hold in RAM at once. */ void init(size_t element_count_, size_t cache_size_) { block_count = (element_count_ / BLOCK_SIZE) + 1; e_count = block_count * BLOCK_SIZE; cache_size = cache_size_; // Initialize vectors cache.resize(cache_size * BLOCK_SIZE); cache_info.resize(cache_size); data_table.resize(block_count); // Set all cache blocks to "not used" for (size_t i=0; i < cache_size; i++) { cache_info[i].priority = 0; cache_info[i].modified = false; cache_info[i].used = false; } // Clear out the data_table pointers memset(&(data_table[0]), 0, sizeof(T*)*block_count); // Initialize the disk cache file with the appropriate size data_file.open(); data_file.seekp((sizeof(T)*e_count)-1); data_file.put('\0'); data_file.flush(); }
/** * Unloads a block from the cache, making sure that any modifications * are written back to disk. */ void unload_cache_block(size_t cb_index) { const size_t b_index = cache_info[cb_index].index; // Clear the reference from the table if (cache_info[cb_index].used) data_table[b_index] = nullptr; // Check if the cache block is modified, and if so, write it to disk if (cache_info[cb_index].modified && cache_info[cb_index].used) { // Seek to the correct place in the file data_file.seekp(sizeof(T)*BLOCK_SIZE*b_index); // Write out the data block const T* i = &(cache[cb_index*BLOCK_SIZE]); data_file.write((char*)i, sizeof(T)*BLOCK_SIZE); // Clear modified tag cache_info[cb_index].modified = false; cache_info[cb_index].used = false; } // Set priority to zero cache_info[cb_index].priority = 0; }