1 /* Copyright 2017-present Facebook, Inc.
2  * Licensed under the Apache License, Version 2.0 */
3 #pragma once
4 #include "watchman_system.h"
5 #include <array>
6 #include "LRUCache.h"
7 #include "watchman_string.h"
8 
9 namespace watchman {
10 struct ContentHashCacheKey {
11   // Path relative to the watched root
12   w_string relativePath;
13   // file size in bytes
14   size_t fileSize;
15   // The modification time
16   struct timespec mtime;
17 
18   // Computes a hash value for use in the cache map
19   std::size_t hashValue() const;
20   bool operator==(const ContentHashCacheKey& other) const;
21 };
22 }
23 
24 namespace std {
25 template <>
26 struct hash<watchman::ContentHashCacheKey> {
27   std::size_t operator()(watchman::ContentHashCacheKey const& key) const {
28     return key.hashValue();
29   }
30 };
31 }
32 
33 namespace watchman {
34 class ContentHashCache {
35  public:
36   using HashValue = std::array<uint8_t, 20>;
37   using Node = LRUCache<ContentHashCacheKey, HashValue>::NodeType;
38 
39   // Construct a cache for a given root, holding the specified
40   // maximum number of items, using the configured negative
41   // caching TTL.
42   ContentHashCache(
43       const w_string& rootPath,
44       size_t maxItems,
45       std::chrono::milliseconds errorTTL);
46 
47   // Obtain the content hash for the given input.
48   // If the result is in the cache it will return a ready future
49   // holding the result.  Otherwise, computeHash will be invoked
50   // to populate the cache.  Returns a future with the result
51   // of the lookup.
52   Future<std::shared_ptr<const Node>> get(const ContentHashCacheKey& key);
53 
54   // Compute the hash value for a given input.
55   // This will block the calling thread while the I/O is performed.
56   // Throws exceptions for any errors that may occur.
57   HashValue computeHashImmediate(const ContentHashCacheKey& key) const;
58 
59   // Compute the hash value for a given input via the thread pool.
60   // Returns a future to operate on the result of this async operation
61   Future<HashValue> computeHash(const ContentHashCacheKey& key) const;
62 
63   // Returns the root path that this cache is associated with
64   const w_string& rootPath() const;
65 
66   // Returns cache statistics
67   CacheStats stats() const;
68 
69  private:
70   LRUCache<ContentHashCacheKey, HashValue> cache_;
71   w_string rootPath_;
72 };
73 }
74