summaryrefslogtreecommitdiff
path: root/src/hdb/filemap.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/hdb/filemap.h')
-rw-r--r--src/hdb/filemap.h196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/hdb/filemap.h b/src/hdb/filemap.h
new file mode 100644
index 0000000..d6af7eb
--- /dev/null
+++ b/src/hdb/filemap.h
@@ -0,0 +1,196 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef FILEMAPH
21#define FILEMAPH
22
23#include <mt/mstring.h>
24#include <mt/lock.h>
25#include <mt/mlock.h>
26#include <mt/mlock.h>
27#include <netinet/in.h>
28
29//////////////////////////////////////////////
30//
31// NOTE that filemap is MT unsafe:
32// it needs to be called from dbmap
33//
34// The exception is when filelocking;
35// that's MT safe per filemap, and hence
36// should not be locked further
37//
38
39#define HEADLOCK(fm) headlock_t headlock(fm)
40
41//////////////////////////////////////////////////////
42
43// network byteorder
44class byte4 {
45public:
46 byte4() {} // must be uninitialized
47 explicit byte4(int h): n(htonl(h)) {}
48 void set(int h) { n=htonl(h); }
49 void add(int h) { n=htonl(ntohl(n)+h); }
50 int get() const { return ntohl(n); }
51private:
52 long n;
53};
54
55//////////////////////////////////////////////////////
56
57class filemap {
58public:
59 typedef char char32[32];
60 static const int maxtabs=32;
61
62 ////////////////////////////////////////////////////
63
64 struct head_t {
65 char32 ident;
66 byte4 lock;
67 byte4 minor;
68 byte4 major;
69 byte4 fatal;
70 byte4 filesize;
71 byte4 filetop;
72 byte4 tables;
73 byte4 index;
74 char32 compname;
75 char32 tabs[maxtabs];
76 byte4 frame;
77
78 head_t();
79 head_t(const head_t* hd,int mem);
80
81 void setcomp(int idx, const sref& cp);
82
83 sref get(int col) const { return sref(tabs[col]); }
84 void set(int col,const sref& s);
85 void insert(int col,const sref& s);
86 void remove(int col);
87 };
88
89 head_t* head() { return hd; }
90 const head_t* head() const { return hd; }
91
92 ///////////////////////////////////////////////////////
93
94 struct rec_t {
95 byte4 mem;
96 byte4 caps;
97 };
98
99 rec_t* at(int off) {
100 for(chunk_t* p=mem;p;p=p->next) if(p->own(off)) return p->at(off); return 0;
101 }
102 const rec_t* at(int off) const {
103 for(const chunk_t* p=mem;p;p=p->next) if(p->own(off)) return p->at(off);
104 return 0;
105 }
106
107 int recs() const { return hd->frame.get(); }
108 int size(int off) const {
109 if(off<hd->filetop.get()) {
110 for(const chunk_t* p=mem;p;p=p->next)
111 if(p->own(off)) return p->at(off)->mem.get();
112 }
113 return 0;
114 }
115
116 ///////////////////////////////////////////////////////
117
118 void remap();
119
120 rec_t* add(int n);
121 void rem(rec_t* rec);
122
123 ///////////////////////////////////////////////////////
124
125 filemap(filemap* p);
126 filemap(filemap* p,const mstring& path,int update=0,int prot=0600);
127 ~filemap();
128
129 filemap* next;
130
131 ///////////////////////////////////////////////////////
132
133 void open(const mstring& path,int update=0,int prot=0600) throw(merror_t);
134 void save(const mstring& path,int prot=0600) throw(merror_t);
135 void check() throw(merror_t);
136 void close();
137 void sync();
138
139 const mstring& Pathname() const { return pathname; }
140 time_t Lastmod() const;
141
142 int reference() const { return refs; }
143 int writable() const { return wok; }
144
145 void pushref() { refs++; }
146 void popref() { refs--; }
147
148 ///////////////////////////////////////////////////////
149
150 void lock();
151 void unlock();
152
153 ///////////////////////////////////////////////////////
154
155protected:
156 struct chunk_t {
157 chunk_t* next;
158 long begin;
159 long end;
160 char* map;
161
162 int size() const { return end-begin; }
163
164 chunk_t(chunk_t* p,int fd,int wok,int off,int size);
165 ~chunk_t();
166
167 int own(int off) const { return off>=begin&&off<end; }
168 void sync();
169
170 rec_t* at(int off) { return (rec_t*)(map+(off-begin)); }
171 const rec_t* at(int off) const { return (rec_t*)(map+(off-begin)); }
172
173 int fill(int off);
174 };
175private:
176 int fd,wok,refs;
177 mstring pathname;
178 head_t* hd;
179 chunk_t* mem;
180 mutex_t mutex;
181 nodelock_t* nodelock;
182private:
183 filemap(const filemap&) {}
184 void operator=(const filemap&) {}
185};
186
187//////////////////////////////////////////////////////
188
189struct headlock_t {
190 filemap* fm;
191 headlock_t(filemap* f) : fm(f) { fm->lock(); }
192 ~headlock_t() { if(fm) fm->unlock(); }
193};
194
195#endif
196