summaryrefslogtreecommitdiff
path: root/src/common/linear_disk_cache.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/linear_disk_cache.h')
-rw-r--r--src/common/linear_disk_cache.h167
1 files changed, 0 insertions, 167 deletions
diff --git a/src/common/linear_disk_cache.h b/src/common/linear_disk_cache.h
deleted file mode 100644
index 94c695163..000000000
--- a/src/common/linear_disk_cache.h
+++ /dev/null
@@ -1,167 +0,0 @@
1// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <fstream>
8#include "common/common_types.h"
9
10// defined in Version.cpp
11extern const char* scm_rev_git_str;
12
13// On disk format:
14// header{
15// u32 'DCAC';
16// u32 version; // svn_rev
17// u16 sizeof(key_type);
18// u16 sizeof(value_type);
19//}
20
21// key_value_pair{
22// u32 value_size;
23// key_type key;
24// value_type[value_size] value;
25//}
26
27template <typename K, typename V>
28class LinearDiskCacheReader {
29public:
30 virtual void Read(const K& key, const V* value, u32 value_size) = 0;
31};
32
33// Dead simple unsorted key-value store with append functionality.
34// No random read functionality, all reading is done in OpenAndRead.
35// Keys and values can contain any characters, including \0.
36//
37// Suitable for caching generated shader bytecode between executions.
38// Not tuned for extreme performance but should be reasonably fast.
39// Does not support keys or values larger than 2GB, which should be reasonable.
40// Keys must have non-zero length; values can have zero length.
41
42// K and V are some POD type
43// K : the key type
44// V : value array type
45template <typename K, typename V>
46class LinearDiskCache {
47public:
48 // return number of read entries
49 u32 OpenAndRead(const char* filename, LinearDiskCacheReader<K, V>& reader) {
50 using std::ios_base;
51
52 // close any currently opened file
53 Close();
54 m_num_entries = 0;
55
56 // try opening for reading/writing
57 OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary);
58
59 m_file.seekg(0, std::ios::end);
60 std::fstream::pos_type end_pos = m_file.tellg();
61 m_file.seekg(0, std::ios::beg);
62 std::fstream::pos_type start_pos = m_file.tellg();
63 std::streamoff file_size = end_pos - start_pos;
64
65 if (m_file.is_open() && ValidateHeader()) {
66 // good header, read some key/value pairs
67 K key;
68
69 V* value = nullptr;
70 u32 value_size;
71 u32 entry_number;
72
73 std::fstream::pos_type last_pos = m_file.tellg();
74
75 while (Read(&value_size)) {
76 std::streamoff next_extent =
77 (last_pos - start_pos) + sizeof(value_size) + value_size;
78 if (next_extent > file_size)
79 break;
80
81 delete[] value;
82 value = new V[value_size];
83
84 // read key/value and pass to reader
85 if (Read(&key) && Read(value, value_size) && Read(&entry_number) &&
86 entry_number == m_num_entries + 1) {
87 reader.Read(key, value, value_size);
88 } else {
89 break;
90 }
91
92 m_num_entries++;
93 last_pos = m_file.tellg();
94 }
95 m_file.seekp(last_pos);
96 m_file.clear();
97
98 delete[] value;
99 return m_num_entries;
100 }
101
102 // failed to open file for reading or bad header
103 // close and recreate file
104 Close();
105 m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary);
106 WriteHeader();
107 return 0;
108 }
109
110 void Sync() {
111 m_file.flush();
112 }
113
114 void Close() {
115 if (m_file.is_open())
116 m_file.close();
117 // clear any error flags
118 m_file.clear();
119 }
120
121 // Appends a key-value pair to the store.
122 void Append(const K& key, const V* value, u32 value_size) {
123 // TODO: Should do a check that we don't already have "key"? (I think each caller does that
124 // already.)
125 Write(&value_size);
126 Write(&key);
127 Write(value, value_size);
128 m_num_entries++;
129 Write(&m_num_entries);
130 }
131
132private:
133 void WriteHeader() {
134 Write(&m_header);
135 }
136
137 bool ValidateHeader() {
138 char file_header[sizeof(Header)];
139
140 return (Read(file_header, sizeof(Header)) &&
141 !memcmp((const char*)&m_header, file_header, sizeof(Header)));
142 }
143
144 template <typename D>
145 bool Write(const D* data, u32 count = 1) {
146 return m_file.write((const char*)data, count * sizeof(D)).good();
147 }
148
149 template <typename D>
150 bool Read(const D* data, u32 count = 1) {
151 return m_file.read((char*)data, count * sizeof(D)).good();
152 }
153
154 struct Header {
155 Header() : id(*(u32*)"DCAC"), key_t_size(sizeof(K)), value_t_size(sizeof(V)) {
156 memcpy(ver, scm_rev_git_str, 40);
157 }
158
159 const u32 id;
160 const u16 key_t_size, value_t_size;
161 char ver[40];
162
163 } m_header;
164
165 std::fstream m_file;
166 u32 m_num_entries;
167};