| 128 | } |
| 129 | |
| 130 | Status PersistentCacheMetaData::Init(uint64_t* recovered_cache_id, PersistentCacheImpl* cache) { |
| 131 | Options opt; |
| 132 | opt.filter_policy = NewBloomFilterPolicy(10); |
| 133 | opt.block_cache = leveldb::NewLRUCache(8UL * 1024 * 1024); |
| 134 | opt.table_cache = new leveldb::TableCache(8UL * 1024 * 1024); |
| 135 | opt.info_log = Logger::DefaultLogger(); |
| 136 | |
| 137 | auto lg_info = new leveldb::LG_info(0); |
| 138 | lg_info->env = NewPosixEnv(); |
| 139 | lg_info->env->SetBackgroundThreads(5); |
| 140 | |
| 141 | opt.lg_info_list = new std::map<uint32_t, leveldb::LG_info*>; |
| 142 | opt.lg_info_list->insert(std::make_pair(0, lg_info)); |
| 143 | opt.use_file_lock = false; // Single process access is guaranteed by ts port. |
| 144 | |
| 145 | DB* db; |
| 146 | auto status = DB::Open(opt, cache->GetMetaPath(), &db); |
| 147 | |
| 148 | if (!status.ok()) { |
| 149 | LEVELDB_LOG("Open persistent cache metadata failed, reason: %s\n", status.ToString().c_str()); |
| 150 | return status; |
| 151 | } |
| 152 | |
| 153 | db_.reset(db); |
| 154 | |
| 155 | ReadOptions read_options(&opt); |
| 156 | read_options.fill_cache = false; |
| 157 | read_options.verify_checksums = true; |
| 158 | std::unique_ptr<Iterator> iterator{db_->NewIterator(read_options)}; |
| 159 | iterator->SeekToFirst(); |
| 160 | uint64_t max_cache_id{0}; |
| 161 | |
| 162 | // db format(kv): |
| 163 | // key -> file_path |
| 164 | // when restore meta data from disk, we get k-v pair from leveldb |
| 165 | // where key is the user cache key, and value is file_path in system |
| 166 | while (iterator->Valid()) { |
| 167 | const Slice key = iterator->key(); |
| 168 | Slice val = iterator->value(); |
| 169 | assert(val.ends_with(".rc")); |
| 170 | |
| 171 | // path format : /xxx/yyy/zzz/k.cache_id.rc |
| 172 | // try extract cache_id from path. |
| 173 | std::string path = val.ToString(); |
| 174 | std::string cache_id_str = path.substr(0, path.size() - 3); |
| 175 | auto last_point_pos = cache_id_str.find_last_of('.'); |
| 176 | assert(last_point_pos != std::string::npos); |
| 177 | cache_id_str = cache_id_str.substr(last_point_pos + 1); |
| 178 | uint64_t cache_id{0}; |
| 179 | |
| 180 | try { |
| 181 | cache_id = std::stoul(cache_id_str); |
| 182 | } catch (...) { |
| 183 | LEVELDB_LOG("[%s] Fail to recover cache_id key: %s, value: %s\n", |
| 184 | cache->GetCachePath().c_str(), key.ToString().c_str(), val.ToString().c_str()); |
| 185 | db->Delete({}, key); |
| 186 | continue; |
| 187 | }; |
no test coverage detected