tesseract 4.1.1
Loading...
Searching...
No Matches
object_cache.h
Go to the documentation of this file.
1
2// 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
28namespace 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().
34template<typename T>
36 public:
37 ObjectCache() = default;
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 = nullptr;
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 nullptr entry in the cache
57 // and return nullptr -- 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,
62 T *retval = nullptr;
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 != nullptr) {
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 != nullptr) ? 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 == nullptr) 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_
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:35
int count(LIST var_list)
Definition: oldlist.cpp:95
int push_back(T object)
int size() const
Definition: genericvector.h:72
void remove(int index)
T & back() const
T * Get(STRING id, TessResultCallback< T * > *loader)
Definition: object_cache.h:60
Definition: strngs.h:45
virtual R Run()=0