Retrieve a random file name to be either opened or deleted. If deleting, the file name is made inaccessible to future operations.
| 243 | // Retrieve a random file name to be either opened or deleted. If deleting, |
| 244 | // the file name is made inaccessible to future operations. |
| 245 | bool GetRandomFile(GetMode mode, Random* rand, string* out) { |
| 246 | std::lock_guard<simple_spinlock> l(lock_); |
| 247 | if (available_files_.empty()) { |
| 248 | return false; |
| 249 | } |
| 250 | |
| 251 | // This is linear time, but it's simpler than managing multiple data |
| 252 | // structures. |
| 253 | auto it = available_files_.begin(); |
| 254 | std::advance(it, rand->Uniform(available_files_.size())); |
| 255 | |
| 256 | // It's unsafe to delete a file that is still being opened. |
| 257 | if (mode == DELETE && it->second > 0) { |
| 258 | return false; |
| 259 | } |
| 260 | |
| 261 | *out = it->first; |
| 262 | if (mode == OPEN) { |
| 263 | it->second++; |
| 264 | } else { |
| 265 | available_files_.erase(it); |
| 266 | } |
| 267 | return true; |
| 268 | } |
| 269 | |
| 270 | // Signal that a previously in-progress open has finished, allowing the file |
| 271 | // in question to be deleted. |