1 : #ifndef TAGCOLL_DISKINDEX_MMAP_H
2 : #define TAGCOLL_DISKINDEX_MMAP_H
3 :
4 : /** \file
5 : * Basic infrastructure for implementing mmapped indexes
6 : */
7 :
8 : /*
9 : * Copyright (C) 2006 Enrico Zini <enrico@debian.org>
10 : *
11 : * This program is free software; you can redistribute it and/or modify
12 : * it under the terms of the GNU General Public License as published by
13 : * the Free Software Foundation; either version 2 of the License, or
14 : * (at your option) any later version.
15 : *
16 : * This program is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU General Public License for more details.
20 : *
21 : * You should have received a copy of the GNU General Public License
22 : * along with this program; if not, write to the Free Software
23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 : */
25 :
26 : #include <string>
27 :
28 : namespace tagcoll {
29 : namespace diskindex {
30 :
31 : class mmap;
32 :
33 : /**
34 : * Performs the memory management and mmapping tasks for mmapped indexes.
35 : *
36 : * One MMap can contain many indexes. Indexes come chained one after the
37 : * other, prefixed by an int that specifies their length:
38 : *
39 : * [size of index 1][index1][size of index 2][index]...
40 : *
41 : * Every index must make sure that its size is int-aligned, otherwise accessing
42 : * it would cause a bus error in many architectures.
43 : */
44 : class MasterMMap
45 : {
46 : protected:
47 : std::string m_filename;
48 : size_t m_size;
49 : int m_fd;
50 : const char* m_buf;
51 :
52 : public:
53 : MasterMMap();
54 : MasterMMap(const std::string& filename);
55 : ~MasterMMap();
56 :
57 : void init(const std::string& filename);
58 :
59 : friend class MMap;
60 : };
61 :
62 : class MMap
63 : {
64 : protected:
65 : const MasterMMap* m_master;
66 : const char* m_buf;
67 : size_t m_size;
68 :
69 : public:
70 : MMap();
71 : MMap(const char* buf, int size);
72 : MMap(const MasterMMap& master, size_t idx);
73 :
74 : void init(const char* buf, int size);
75 : void init(const MasterMMap& master, size_t idx);
76 :
77 : /// Round a value to the next word size in the current architecture
78 : template<class INT>
79 12 : static inline INT align(INT val)
80 : {
81 12 : return (val + sizeof(int) - 1) & ~(sizeof(int) - 1);
82 : }
83 : };
84 :
85 : /**
86 : * Interface for indexers.
87 : */
88 : class MMapIndexer
89 20 : {
90 : public:
91 20 : virtual ~MMapIndexer() {}
92 :
93 : /// Return the size of the encoded index data (in bytes)
94 : virtual int encodedSize() const = 0;
95 :
96 : /// Write the index data in the given buffer, which should be at least
97 : /// encodedSize bytes
98 : virtual void encode(char* buf) const = 0;
99 : };
100 :
101 : /**
102 : * Master index writer. It allows to write many indexes in the same file,
103 : * atomically: the file will be created as a tempfile and atomically renamed to
104 : * the destination filename on class destruction.
105 : */
106 : class MasterMMapIndexer
107 : {
108 : protected:
109 : std::string finalname;
110 : std::string tmpname;
111 : int fd;
112 :
113 : public:
114 : MasterMMapIndexer(const std::string& filename);
115 : ~MasterMMapIndexer();
116 :
117 : /// Close the file and perform the final rename
118 : void commit();
119 :
120 : /// Append one subindex
121 : void append(const MMapIndexer& idx);
122 : };
123 :
124 :
125 : }
126 : }
127 :
128 : // vim:set ts=4 sw=4:
129 : #endif
|