All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
object_cache.h
Go to the documentation of this file.
1 // File: object_cache.h
3 // Description: A string indexed object cache.
4 // Author: David Eger
5 // Created: Fri Jan 27 12:08:00 PST 2012
6 //
7 // (C) Copyright 2012, Google Inc.
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
12 // Unless required by applicable law or agreed to in writing, software
13 // distributed under the License is distributed on an "AS IS" BASIS,
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 // See the License for the specific language governing permissions and
16 // limitations under the License.
17 //
19 
20 #ifndef TESSERACT_CCUTIL_OBJECT_CACHE_H_
21 #define TESSERACT_CCUTIL_OBJECT_CACHE_H_
22 
23 #include "ccutil.h"
24 #include "errcode.h"
25 #include "genericvector.h"
26 #include "tesscallback.h"
27 
28 namespace tesseract {
29 
30 // A simple object cache which maps a string to an object of type T.
31 // Usually, these are expensive objects that are loaded from disk.
32 // Reference counting is performed, so every Get() needs to be followed later
33 // by a Free(). Actual deletion is accomplished by DeleteUnusedObjects().
34 template<typename T>
35 class ObjectCache {
36  public:
39  mu_.Lock();
40  for (int i = 0; i < cache_.size(); i++) {
41  if (cache_[i].count > 0) {
42  tprintf("ObjectCache(%p)::~ObjectCache(): WARNING! LEAK! object %p "
43  "still has count %d (id %s)\n",
44  this, cache_[i].object, cache_[i].count,
45  cache_[i].id.string());
46  } else {
47  delete cache_[i].object;
48  cache_[i].object = NULL;
49  }
50  }
51  mu_.Unlock();
52  }
53 
54  // Return a pointer to the object identified by id.
55  // If we haven't yet loaded the object, use loader to load it.
56  // If loader fails to load it, record a NULL entry in the cache
57  // and return NULL -- further attempts to load will fail (even
58  // with a different loader) until DeleteUnusedObjects() is called.
59  // We delete the given loader.
60  T *Get(STRING id,
61  TessResultCallback<T *> *loader) {
62  T *retval = NULL;
63  mu_.Lock();
64  for (int i = 0; i < cache_.size(); i++) {
65  if (id == cache_[i].id) {
66  retval = cache_[i].object;
67  if (cache_[i].object != NULL) {
68  cache_[i].count++;
69  }
70  mu_.Unlock();
71  delete loader;
72  return retval;
73  }
74  }
75  cache_.push_back(ReferenceCount());
76  ReferenceCount &rc = cache_.back();
77  rc.id = id;
78  retval = rc.object = loader->Run();
79  rc.count = (retval != NULL) ? 1 : 0;
80  mu_.Unlock();
81  return retval;
82  }
83 
84  // Decrement the count for t.
85  // Return whether we knew about the given pointer.
86  bool Free(T *t) {
87  if (t == NULL) return false;
88  mu_.Lock();
89  for (int i = 0; i < cache_.size(); i++) {
90  if (cache_[i].object == t) {
91  --cache_[i].count;
92  mu_.Unlock();
93  return true;
94  }
95  }
96  mu_.Unlock();
97  return false;
98  }
99 
101  mu_.Lock();
102  for (int i = cache_.size() - 1; i >= 0; i--) {
103  if (cache_[i].count <= 0) {
104  delete cache_[i].object;
105  cache_.remove(i);
106  }
107  }
108  mu_.Unlock();
109  }
110 
111  private:
112  struct ReferenceCount {
113  STRING id; // A unique ID to identify the object (think path on disk)
114  T *object; // A copy of the object in memory. Can be delete'd.
115  int count; // A count of the number of active users of this object.
116  };
117 
118  CCUtilMutex mu_;
120 };
121 
122 } // namespace tesseract
123 
124 
125 #endif // TESSERACT_CCUTIL_OBJECT_CACHE_H_
int size() const
Definition: genericvector.h:72
int push_back(T object)
#define tprintf(...)
Definition: tprintf.h:31
T & back() const
virtual R Run()=0
T * Get(STRING id, TessResultCallback< T * > *loader)
Definition: object_cache.h:60
void remove(int index)
int count(LIST var_list)
Definition: oldlist.cpp:108
Definition: strngs.h:44
#define NULL
Definition: host.h:144