blob: 3ce15fbec7e310539d271c3a4746607cde8f2865 [file] [log] [blame]
John Bauman89401822014-05-06 15:04:28 -04001// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2011 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12#ifndef sw_LRUCache_hpp
13#define sw_LRUCache_hpp
14
15#include "Common/Math.hpp"
16
17namespace sw
18{
19 template<class Key, class Data>
20 class LRUCache
21 {
22 public:
23 LRUCache(int n);
24
25 ~LRUCache();
26
27 Data *query(const Key &key) const;
28 Data *add(const Key &key, Data *data);
29
30 int getSize() {return size;}
31 Key &getKey(int i) {return key[i];}
32
33 private:
34 int size;
35 int mask;
36 int top;
37 int fill;
38
39 Key *key;
40 Key **ref;
41 Data **data;
42 };
43}
44
45namespace sw
46{
47 template<class Key, class Data>
48 LRUCache<Key, Data>::LRUCache(int n)
49 {
50 size = ceilPow2(n);
51 mask = size - 1;
52 top = 0;
53 fill = 0;
54
55 key = new Key[size];
56 ref = new Key*[size];
57 data = new Data*[size];
58
59 for(int i = 0; i < size; i++)
60 {
61 data[i] = 0;
62
63 ref[i] = &key[i];
64 }
65 }
66
67 template<class Key, class Data>
68 LRUCache<Key, Data>::~LRUCache()
69 {
70 delete[] key;
71 key = 0;
72
73 delete[] ref;
74 ref = 0;
75
76 for(int i = 0; i < size; i++)
77 {
78 if(data[i])
79 {
80 data[i]->unbind();
81 data[i] = 0;
82 }
83 }
84
85 delete[] data;
86 data = 0;
87 }
88
89 template<class Key, class Data>
90 Data *LRUCache<Key, Data>::query(const Key &key) const
91 {
92 for(int i = top; i > top - fill; i--)
93 {
94 int j = i & mask;
95
96 if(key == *ref[j])
97 {
98 Data *hit = data[j];
99
100 if(i != top)
101 {
102 // Move one up
103 int k = (j + 1) & mask;
104
105 Data *swapD = data[k];
106 data[k] = data[j];
107 data[j] = swapD;
108
109 Key *swapK = ref[k];
110 ref[k] = ref[j];
111 ref[j] = swapK;
112 }
113
114 return hit;
115 }
116 }
117
118 return 0; // Not found
119 }
120
121 template<class Key, class Data>
122 Data *LRUCache<Key, Data>::add(const Key &key, Data *data)
123 {
124 top = (top + 1) & mask;
125 fill = fill + 1 < size ? fill + 1 : size;
126
127 *ref[top] = key;
128
129 data->bind();
130
131 if(this->data[top])
132 {
133 this->data[top]->unbind();
134 }
135
136 this->data[top] = data;
137
138 return data;
139 }
140}
141
142#endif // sw_LRUCache_hpp