HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_AgentFileCache.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GU_AgentFileCache.h (GU Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GU_AgentFileCache__
12 #define __GU_AgentFileCache__
13 
14 #include "GU_API.h"
15 
16 #include <FS/FS_Info.h>
18 #include <UT/UT_IntrusivePtr.h>
19 #include <UT/UT_WorkBuffer.h>
20 
21 template <typename T>
23 {
24 public:
25  /// Searches for a cached file with the same key, and returns it if the
26  /// timestamp matches the file on disk. Otherwise, the callback is invoked
27  /// to load the file, which is then inserted into the cache and returned.
28  /// The key should include the filename and any dependencies on other agent
29  /// files (e.g. when loading the same clip for slightly different rigs).
30  template <typename F>
32  const UT_StringRef &key,
33  F load_new_item);
34 
35  /// Removes a cached file with the given key.
36  void removeCachedFile(const UT_StringRef &key);
37 
38 private:
39  struct CachedFile
40  {
41  CachedFile(T *ptr = nullptr, time_t mod_time = 0)
42  : myPtr(ptr), myModTime(mod_time)
43  {
44  }
45 
46  T *myPtr;
47  time_t myModTime;
48  };
49 
50  using CachedFileMap = UT_ConcurrentHashMap<UT_StringHolder, CachedFile>;
51  CachedFileMap myFiles;
52 };
53 
54 /// Builds a list of paths to use when attempting to load an external file,
55 /// ordered by priority.
57  const UT_StringHolder &condensed_path,
58  const UT_StringHolder &expanded_path);
59 
60 template <typename T>
61 template <typename F>
62 inline UT_IntrusivePtr<T>
64  const UT_StringRef &key,
65  F load_new_item)
66 {
67  FS_Info info(filename);
68  time_t mod_time = 0;
69  if (info.hasAccess())
70  mod_time = info.getModTime();
71 
72  // First, do a quick check to see if there's a valid entry.
73  {
74  typename CachedFileMap::const_accessor acc;
75  if (myFiles.find(acc, UTmakeUnsafeRef(key)) &&
76  acc->second.myModTime == mod_time)
77  {
78  return acc->second.myPtr;
79  }
80  }
81 
82  typename CachedFileMap::accessor acc;
83  if (myFiles.insert(acc, key) || acc->second.myModTime != mod_time)
84  {
85  // If the item was not in the cache or is out of date, load it.
86  auto new_item = load_new_item();
87  if (new_item)
88  acc->second = CachedFile(new_item.get(), mod_time);
89  else
90  {
91  // If the item failed to load, remove the empty entry from the map.
92  // Note that this erasure might also happen at the same time from
93  // removeCachedFile() but that's ok.
94  (void) myFiles.erase(acc);
95  }
96 
97  return new_item;
98  }
99  else
100  return acc->second.myPtr;
101 }
102 
103 template <typename T>
104 inline void
106 {
107  myFiles.erase(key);
108 }
109 
110 #endif
GT_API const UT_StringHolder filename
bool hasAccess(int mode=0) const
GU_API void GUgetAgentFilePaths(UT_StringArray &paths, const UT_StringHolder &condensed_path, const UT_StringHolder &expanded_path)
void
Definition: png.h:1083
SYS_FORCE_INLINE const UT_StringHolder & UTmakeUnsafeRef(const UT_StringRef &ref)
Convert a UT_StringRef into a UT_StringHolder that is a shallow reference.
void removeCachedFile(const UT_StringRef &key)
Removes a cached file with the given key.
Wrapper around hboost::intrusive_ptr.
#define GU_API
Definition: GU_API.h:14
UT_IntrusivePtr< T > findCachedFileOrLoad(const UT_StringRef &filename, const UT_StringRef &key, F load_new_item)
time_t getModTime() const
auto ptr(T p) -> const void *
Definition: format.h:2448
Class for retrieving file information.
Definition: FS_Info.h:98
GLenum const void * paths
Definition: glew.h:13872