1 | // =============================================================== // |
---|
2 | // // |
---|
3 | // File : ps_database.hxx // |
---|
4 | // Purpose : // |
---|
5 | // // |
---|
6 | // Coded by Wolfram Foerster in October 2002 // |
---|
7 | // Institute of Microbiology (Technical University Munich) // |
---|
8 | // http://www.arb-home.de/ // |
---|
9 | // // |
---|
10 | // =============================================================== // |
---|
11 | |
---|
12 | #ifndef PS_DATABASE_HXX |
---|
13 | #define PS_DATABASE_HXX |
---|
14 | |
---|
15 | #ifndef PS_NODE_HXX |
---|
16 | #include "ps_node.hxx" |
---|
17 | #endif |
---|
18 | |
---|
19 | using namespace std; |
---|
20 | |
---|
21 | class PS_Database FINAL_TYPE : PS_Callback, virtual Noncopyable { |
---|
22 | private: |
---|
23 | string FILE_ID; |
---|
24 | |
---|
25 | // file |
---|
26 | PS_FileBuffer *db_file; |
---|
27 | |
---|
28 | // ID<->name mappings |
---|
29 | Name2IDMap db_name2id_map; |
---|
30 | ID2NameMap db_id2name_map; |
---|
31 | |
---|
32 | // tree |
---|
33 | PS_NodePtr db_rootnode; |
---|
34 | |
---|
35 | bool readHeader(PS_FileBuffer *_file); |
---|
36 | void writeHeader(PS_FileBuffer *_file); |
---|
37 | |
---|
38 | void readMappings(PS_FileBuffer *_file, ID2NameMap &_id2name_map, Name2IDMap &_name2id_map); |
---|
39 | void writeMappings(PS_FileBuffer *_file, ID2NameMap &_id2name_map); |
---|
40 | |
---|
41 | void readTree(PS_FileBuffer *_file); |
---|
42 | void writeTree(PS_FileBuffer *_file); |
---|
43 | |
---|
44 | // tree merging data structures and functions |
---|
45 | ID2IDMap db_file2db_id_map; |
---|
46 | PS_NodePtr db_path; |
---|
47 | SpeciesID db_MAX_ID; |
---|
48 | |
---|
49 | void callback(void *_caller) OVERRIDE; |
---|
50 | |
---|
51 | public: |
---|
52 | static const bool READONLY = true; |
---|
53 | static const bool WRITEONLY = false; |
---|
54 | |
---|
55 | // |
---|
56 | // I/O |
---|
57 | // |
---|
58 | bool load() { |
---|
59 | if (!db_file->isReadonly()) return false; // cannot read a writeonly file |
---|
60 | if (!readHeader(db_file)) return false; // not a file i wrote |
---|
61 | readMappings(db_file, db_id2name_map, db_name2id_map); |
---|
62 | readTree(db_file); |
---|
63 | return true; |
---|
64 | } |
---|
65 | |
---|
66 | bool save() { |
---|
67 | if (db_file->isReadonly()) return false; // cannot write to a readonly file |
---|
68 | writeHeader(db_file); |
---|
69 | writeMappings(db_file, db_id2name_map); |
---|
70 | writeTree(db_file); |
---|
71 | return true; |
---|
72 | } |
---|
73 | |
---|
74 | bool saveTo(const char *_filename) { |
---|
75 | PS_FileBuffer *file = new PS_FileBuffer(_filename, PS_FileBuffer::WRITEONLY); |
---|
76 | writeHeader(file); |
---|
77 | writeMappings(file, db_id2name_map); |
---|
78 | writeTree(file); |
---|
79 | if (file) delete file; |
---|
80 | return true; |
---|
81 | } |
---|
82 | |
---|
83 | bool merge(const char *_other_db_name); |
---|
84 | |
---|
85 | // |
---|
86 | // access tree |
---|
87 | // |
---|
88 | PS_NodePtr getRootNode() { |
---|
89 | return db_rootnode; |
---|
90 | } |
---|
91 | const PS_NodePtr getConstRootNode() { |
---|
92 | return db_rootnode; |
---|
93 | } |
---|
94 | |
---|
95 | // |
---|
96 | // access mappings |
---|
97 | // |
---|
98 | bool getIDForName(SpeciesID &_id, const string &_name) { |
---|
99 | Name2IDMapCIter it = db_name2id_map.find(_name); |
---|
100 | if (it != db_name2id_map.end()) { |
---|
101 | _id = it->second; |
---|
102 | return true; |
---|
103 | } |
---|
104 | else { |
---|
105 | return false; |
---|
106 | } |
---|
107 | } |
---|
108 | |
---|
109 | bool getNameForID(const SpeciesID _id, string &_name) { |
---|
110 | ID2NameMapCIter it = db_id2name_map.find(_id); |
---|
111 | if (it != db_id2name_map.end()) { |
---|
112 | _name = it->second; |
---|
113 | return true; |
---|
114 | } |
---|
115 | else { |
---|
116 | return false; |
---|
117 | } |
---|
118 | } |
---|
119 | |
---|
120 | bool insertMapping(SpeciesID _id, const string &_name) { |
---|
121 | ID2NameMapCIter it = db_id2name_map.find(_id); |
---|
122 | if (it != db_id2name_map.end()) { |
---|
123 | return it->second.compare(_name) == 0; // return false if _name is not the string already stored for _id |
---|
124 | } |
---|
125 | else { |
---|
126 | db_id2name_map[_id] = _name; |
---|
127 | db_name2id_map[_name] = _id; |
---|
128 | return true; |
---|
129 | } |
---|
130 | } |
---|
131 | |
---|
132 | void setMappings(Name2IDMap &_name2id, ID2NameMap &_id2name) { |
---|
133 | db_name2id_map.clear(); |
---|
134 | db_name2id_map = Name2IDMap(_name2id); |
---|
135 | db_id2name_map.clear(); |
---|
136 | db_id2name_map = ID2NameMap(_id2name); |
---|
137 | } |
---|
138 | |
---|
139 | SpeciesID getMaxID() { |
---|
140 | return db_id2name_map.rbegin()->first; |
---|
141 | } |
---|
142 | SpeciesID getMinID() { |
---|
143 | return db_id2name_map.begin()->first; |
---|
144 | } |
---|
145 | long getSpeciesCount() { |
---|
146 | return db_id2name_map.size(); |
---|
147 | } |
---|
148 | |
---|
149 | // |
---|
150 | // utility-functions |
---|
151 | // |
---|
152 | bool isReadonly() { return db_file->isReadonly(); } |
---|
153 | |
---|
154 | // |
---|
155 | // initialization-functions |
---|
156 | // |
---|
157 | void reinit(const char *_name, bool _readonly); // reinit. with new file |
---|
158 | |
---|
159 | PS_Database(const char *_name, bool _readonly) |
---|
160 | : FILE_ID("PROBE_SET_DATABASE V1.0\n"), |
---|
161 | db_file(NULp) |
---|
162 | { |
---|
163 | db_rootnode.setNull(); |
---|
164 | reinit(_name, _readonly); |
---|
165 | } |
---|
166 | |
---|
167 | ~PS_Database() OVERRIDE { |
---|
168 | if (db_file) delete db_file; |
---|
169 | db_name2id_map.clear(); |
---|
170 | db_id2name_map.clear(); |
---|
171 | db_rootnode.setNull(); |
---|
172 | } |
---|
173 | |
---|
174 | }; |
---|
175 | |
---|
176 | #else |
---|
177 | #error ps_database.hxx included twice |
---|
178 | #endif // PS_DATABASE_HXX |
---|