summaryrefslogtreecommitdiff
path: root/src/common/linear_disk_cache.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/common/linear_disk_cache.h78
1 files changed, 29 insertions, 49 deletions
diff --git a/src/common/linear_disk_cache.h b/src/common/linear_disk_cache.h
index 48529cf42..94c695163 100644
--- a/src/common/linear_disk_cache.h
+++ b/src/common/linear_disk_cache.h
@@ -4,31 +4,30 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h"
8#include <fstream> 7#include <fstream>
8#include "common/common_types.h"
9 9
10// defined in Version.cpp 10// defined in Version.cpp
11extern const char *scm_rev_git_str; 11extern const char* scm_rev_git_str;
12 12
13// On disk format: 13// On disk format:
14//header{ 14// header{
15// u32 'DCAC'; 15// u32 'DCAC';
16// u32 version; // svn_rev 16// u32 version; // svn_rev
17// u16 sizeof(key_type); 17// u16 sizeof(key_type);
18// u16 sizeof(value_type); 18// u16 sizeof(value_type);
19//} 19//}
20 20
21//key_value_pair{ 21// key_value_pair{
22// u32 value_size; 22// u32 value_size;
23// key_type key; 23// key_type key;
24// value_type[value_size] value; 24// value_type[value_size] value;
25//} 25//}
26 26
27template <typename K, typename V> 27template <typename K, typename V>
28class LinearDiskCacheReader 28class LinearDiskCacheReader {
29{
30public: 29public:
31 virtual void Read(const K &key, const V *value, u32 value_size) = 0; 30 virtual void Read(const K& key, const V* value, u32 value_size) = 0;
32}; 31};
33 32
34// Dead simple unsorted key-value store with append functionality. 33// Dead simple unsorted key-value store with append functionality.
@@ -44,12 +43,10 @@ public:
44// K : the key type 43// K : the key type
45// V : value array type 44// V : value array type
46template <typename K, typename V> 45template <typename K, typename V>
47class LinearDiskCache 46class LinearDiskCache {
48{
49public: 47public:
50 // return number of read entries 48 // return number of read entries
51 u32 OpenAndRead(const char *filename, LinearDiskCacheReader<K, V> &reader) 49 u32 OpenAndRead(const char* filename, LinearDiskCacheReader<K, V>& reader) {
52 {
53 using std::ios_base; 50 using std::ios_base;
54 51
55 // close any currently opened file 52 // close any currently opened file
@@ -65,20 +62,19 @@ public:
65 std::fstream::pos_type start_pos = m_file.tellg(); 62 std::fstream::pos_type start_pos = m_file.tellg();
66 std::streamoff file_size = end_pos - start_pos; 63 std::streamoff file_size = end_pos - start_pos;
67 64
68 if (m_file.is_open() && ValidateHeader()) 65 if (m_file.is_open() && ValidateHeader()) {
69 {
70 // good header, read some key/value pairs 66 // good header, read some key/value pairs
71 K key; 67 K key;
72 68
73 V *value = nullptr; 69 V* value = nullptr;
74 u32 value_size; 70 u32 value_size;
75 u32 entry_number; 71 u32 entry_number;
76 72
77 std::fstream::pos_type last_pos = m_file.tellg(); 73 std::fstream::pos_type last_pos = m_file.tellg();
78 74
79 while (Read(&value_size)) 75 while (Read(&value_size)) {
80 { 76 std::streamoff next_extent =
81 std::streamoff next_extent = (last_pos - start_pos) + sizeof(value_size) + value_size; 77 (last_pos - start_pos) + sizeof(value_size) + value_size;
82 if (next_extent > file_size) 78 if (next_extent > file_size)
83 break; 79 break;
84 80
@@ -86,15 +82,10 @@ public:
86 value = new V[value_size]; 82 value = new V[value_size];
87 83
88 // read key/value and pass to reader 84 // read key/value and pass to reader
89 if (Read(&key) && 85 if (Read(&key) && Read(value, value_size) && Read(&entry_number) &&
90 Read(value, value_size) && 86 entry_number == m_num_entries + 1) {
91 Read(&entry_number) &&
92 entry_number == m_num_entries+1)
93 {
94 reader.Read(key, value, value_size); 87 reader.Read(key, value, value_size);
95 } 88 } else {
96 else
97 {
98 break; 89 break;
99 } 90 }
100 91
@@ -116,13 +107,11 @@ public:
116 return 0; 107 return 0;
117 } 108 }
118 109
119 void Sync() 110 void Sync() {
120 {
121 m_file.flush(); 111 m_file.flush();
122 } 112 }
123 113
124 void Close() 114 void Close() {
125 {
126 if (m_file.is_open()) 115 if (m_file.is_open())
127 m_file.close(); 116 m_file.close();
128 // clear any error flags 117 // clear any error flags
@@ -130,9 +119,9 @@ public:
130 } 119 }
131 120
132 // Appends a key-value pair to the store. 121 // Appends a key-value pair to the store.
133 void Append(const K &key, const V *value, u32 value_size) 122 void Append(const K& key, const V* value, u32 value_size) {
134 { 123 // TODO: Should do a check that we don't already have "key"? (I think each caller does that
135 // TODO: Should do a check that we don't already have "key"? (I think each caller does that already.) 124 // already.)
136 Write(&value_size); 125 Write(&value_size);
137 Write(&key); 126 Write(&key);
138 Write(value, value_size); 127 Write(value, value_size);
@@ -141,38 +130,29 @@ public:
141 } 130 }
142 131
143private: 132private:
144 void WriteHeader() 133 void WriteHeader() {
145 {
146 Write(&m_header); 134 Write(&m_header);
147 } 135 }
148 136
149 bool ValidateHeader() 137 bool ValidateHeader() {
150 {
151 char file_header[sizeof(Header)]; 138 char file_header[sizeof(Header)];
152 139
153 return (Read(file_header, sizeof(Header)) 140 return (Read(file_header, sizeof(Header)) &&
154 && !memcmp((const char*)&m_header, file_header, sizeof(Header))); 141 !memcmp((const char*)&m_header, file_header, sizeof(Header)));
155 } 142 }
156 143
157 template <typename D> 144 template <typename D>
158 bool Write(const D *data, u32 count = 1) 145 bool Write(const D* data, u32 count = 1) {
159 {
160 return m_file.write((const char*)data, count * sizeof(D)).good(); 146 return m_file.write((const char*)data, count * sizeof(D)).good();
161 } 147 }
162 148
163 template <typename D> 149 template <typename D>
164 bool Read(const D *data, u32 count = 1) 150 bool Read(const D* data, u32 count = 1) {
165 {
166 return m_file.read((char*)data, count * sizeof(D)).good(); 151 return m_file.read((char*)data, count * sizeof(D)).good();
167 } 152 }
168 153
169 struct Header 154 struct Header {
170 { 155 Header() : id(*(u32*)"DCAC"), key_t_size(sizeof(K)), value_t_size(sizeof(V)) {
171 Header()
172 : id(*(u32*)"DCAC")
173 , key_t_size(sizeof(K))
174 , value_t_size(sizeof(V))
175 {
176 memcpy(ver, scm_rev_git_str, 40); 156 memcpy(ver, scm_rev_git_str, 40);
177 } 157 }
178 158