| 148 | } |
| 149 | |
| 150 | bool DirIvCache::lookup(LPCWSTR path, unsigned char *dir_iv) |
| 151 | { |
| 152 | wstring key = path; |
| 153 | |
| 154 | bool found; |
| 155 | |
| 156 | normalize_key(key); |
| 157 | |
| 158 | lock(); |
| 159 | |
| 160 | m_lookups++; |
| 161 | |
| 162 | auto it = m_map.find(key); |
| 163 | |
| 164 | if (it != m_map.end()) { |
| 165 | |
| 166 | DirIvCacheNode *node = it->second; |
| 167 | |
| 168 | // If the node's TTL has expired, then check if the diriv file's last write time has changed. |
| 169 | // If it has changed, then remove the node, add it to the spare node list, and return a miss. |
| 170 | // This is done in order to have some sort of coherency if other systems are modifying a synced filesystem. |
| 171 | |
| 172 | if (check_node_clean(node, key)) { |
| 173 | |
| 174 | // The entry is less than TTL old or the diriv file is unmodified, so use it. |
| 175 | |
| 176 | memcpy(dir_iv, node->m_dir_iv, DIR_IV_LEN); |
| 177 | |
| 178 | update_lru(node); |
| 179 | found = true; |
| 180 | m_hits++; |
| 181 | |
| 182 | } else { |
| 183 | |
| 184 | // The entry is no longer valid. Remove it, add it to the spare list, and return a miss. |
| 185 | |
| 186 | m_map.erase(it); |
| 187 | |
| 188 | m_lru_list.erase(node->m_list_it); |
| 189 | |
| 190 | m_spare_node_list.push_front(node); |
| 191 | |
| 192 | found = false; |
| 193 | } |
| 194 | } else { |
| 195 | found = false; |
| 196 | } |
| 197 | |
| 198 | if (m_lookups && (m_lookups % 1024 == 0)) { |
| 199 | double ratio = (double)m_hits / (double)m_lookups; |
| 200 | //DbgPrint(L"DirIvCache: %I64d lookups, %I64d hits, %I64d misses, hit ratio %0.2f%%\n", m_lookups, m_hits, m_lookups - m_hits, ratio*100); |
| 201 | } |
| 202 | |
| 203 | unlock(); |
| 204 | |
| 205 | return found; |
| 206 | } |
| 207 | |