6
6
#include < gtl/db/odb_object.hpp>
7
7
#include < boost/iostreams/filter/zlib.hpp>
8
8
#include < boost/filesystem.hpp>
9
+ #include < cstring>
9
10
10
11
GTL_HEADER_BEGIN
11
12
GTL_NAMESPACE_BEGIN
@@ -64,11 +65,18 @@ class odb_loose_output_object
64
65
typedef typename traits_type::object_type object_type;
65
66
typedef odb_loose_output_object this_type;
66
67
68
+ private:
69
+ // ! Initialize our stream for reading, basically read-in the header information
70
+ // ! and keep the stream available for actual data reading
71
+ void init () const {
72
+ m_initialized = true ;
73
+ }
74
+
67
75
protected:
68
- path_type m_path;
69
- bool m_initialized;
70
- size_type m_size;
71
- object_type m_obj_type;
76
+ path_type m_path;
77
+ mutable bool m_initialized;
78
+ mutable size_type m_size;
79
+ mutable object_type m_obj_type;
72
80
73
81
public:
74
82
@@ -100,12 +108,16 @@ class odb_loose_output_object
100
108
}
101
109
102
110
object_type type () const {
103
- // todo init info
111
+ if (!m_initialized){
112
+ init ();
113
+ }
104
114
return m_obj_type;
105
115
}
106
116
107
117
size_type size () const {
108
- // todo initialize
118
+ if (!m_initialized){
119
+ init ();
120
+ }
109
121
return m_size;
110
122
}
111
123
@@ -120,6 +132,7 @@ class odb_loose_output_object
120
132
121
133
// ! modifyable version of our internal path
122
134
path_type& path () {
135
+ m_initialized = false ; // could change the path, and usually does !
123
136
return m_path;
124
137
}
125
138
@@ -138,52 +151,78 @@ class loose_accessor : public odb_accessor<ObjectTraits>
138
151
typedef typename traits_type::key_type key_type;
139
152
typedef typename traits_type::size_type size_type;
140
153
typedef typename traits_type::object_type object_type;
154
+ typedef typename db_traits_type::path_type path_type;
141
155
typedef loose_accessor<traits_type, db_traits_type> this_type;
142
156
143
157
protected:
144
- key_type m_key;
145
158
mutable output_object_type m_obj;
146
159
147
160
protected:
148
161
// ! Default constructor, only for derived types
149
- loose_accessor () {}
162
+ loose_accessor (){}
150
163
151
164
public:
152
165
// ! Initialize this instance with a key to operate upon.
153
166
// ! It should, but is not required, to point to a valid object
154
- loose_accessor (const key_type& key )
155
- : m_key(key )
167
+ loose_accessor (const path_type& objpath )
168
+ : m_obj(objpath )
156
169
{}
157
170
171
+ loose_accessor (const this_type& rhs)
172
+ : m_obj(rhs.m_obj)
173
+ {}
174
+
175
+ loose_accessor (this_type&&) = default ;
176
+
158
177
// ! Equality comparison of compatible iterators
159
178
inline bool operator ==(const this_type& rhs) const {
160
- return m_key == rhs.m_key ;
179
+ return m_obj == rhs.m_obj ;
161
180
}
162
181
163
182
// ! Inequality comparison
164
183
inline bool operator !=(const this_type& rhs) const {
165
- return !(m_key == rhs.m_key );
184
+ return !(m_obj == rhs.m_obj );
166
185
}
167
186
168
187
// ! allows access to the actual input object
169
188
inline const output_object_type& operator *() const {
170
- // initialize if required
171
189
return m_obj;
172
190
}
173
191
174
192
// ! allow -> semantics
175
193
inline const output_object_type* operator ->() const {
176
- // initialize if required
177
194
return &m_obj;
178
195
}
179
196
180
197
public:
181
- const key_type& key () const {
182
- return m_key;
198
+ // ! \return key matching our path
199
+ // ! \note this generates the key instance from our object's path
200
+ // ! \todo implementation could be more efficient by manually parsing the path's buffer - if we
201
+ // ! make plenty of assumptions, this would be easy to write too.
202
+ key_type key () const {
203
+ // convert path to temporary key
204
+ typedef typename fs::path::string_type::value_type char_type;
205
+ typedef typename fs::path::string_type string_type;
206
+ assert (!m_obj.path ().empty ());
207
+
208
+ string_type filename = m_obj.path ().filename ();
209
+ string_type parent_dir = m_obj.path ().parent_path ().filename ();
210
+ assert (filename.size ()/2 == key_type::hash_len - db_traits_type::num_prefix_characters);
211
+ assert (parent_dir.size ()/2 == db_traits_type::num_prefix_characters);
212
+
213
+ // try to be more efficient regarding allocation by reserving the pre-determined
214
+ // mount of bytes. Could be static buffer.
215
+ string_type tmp;
216
+ tmp.reserve (key_type::hash_len*2 );
217
+ tmp.insert (tmp.end (), parent_dir.begin (), parent_dir.end ());
218
+ tmp.insert (tmp.end (), filename.begin (), filename.end ());
219
+
220
+ return key_type (tmp);
183
221
}
184
222
185
223
};
186
224
225
+
187
226
/* * \brief iterator for all loose objects in the database.
188
227
* It iterates folders and files within these folders until the folder interation is depleted.
189
228
* \todo derive from boost::iterator_facade, which would allow to remove plenty of boilerplate
@@ -203,7 +242,6 @@ class loose_forward_iterator : public loose_accessor<ObjectTraits, Traits>
203
242
204
243
protected:
205
244
boost::filesystem::recursive_directory_iterator m_iter;
206
- output_object_type m_obj; // object at current iteration
207
245
208
246
protected:
209
247
// ! increment our iterator to the next object file
@@ -221,8 +259,7 @@ class loose_forward_iterator : public loose_accessor<ObjectTraits, Traits>
221
259
if (path.filename ().size ()/2 == key_type::hash_len - db_traits_type::num_prefix_characters &&
222
260
(*(--(--path.end ()))).size ()/2 == db_traits_type::num_prefix_characters)
223
261
{
224
- m_obj = output_object_type (path);
225
- std::cerr << " Found one: " << path.filename () << std::endl;
262
+ this ->m_obj .path () = path;
226
263
break ;
227
264
}
228
265
}
@@ -232,18 +269,20 @@ class loose_forward_iterator : public loose_accessor<ObjectTraits, Traits>
232
269
public:
233
270
loose_forward_iterator (const path_type& root)
234
271
: m_iter(root)
235
- {}
272
+ {next (); }
236
273
237
274
// ! default constructor, used as end iterator
238
275
loose_forward_iterator ()
239
276
{}
240
277
241
278
// ! copy constructor
242
279
loose_forward_iterator (const this_type& rhs)
243
- : m_iter (rhs.m_iter )
244
- , m_obj (rhs.m_obj)
280
+ : loose_accessor<ObjectTraits, Traits> (rhs)
281
+ , m_iter (rhs.m_iter)
245
282
{}
246
283
284
+ loose_forward_iterator (this_type&&) = default ;
285
+
247
286
// ! Equality comparison of compatible iterators
248
287
inline bool operator ==(const this_type& rhs) const {
249
288
return m_iter == rhs.m_iter ;
@@ -262,24 +301,6 @@ class loose_forward_iterator : public loose_accessor<ObjectTraits, Traits>
262
301
this_type cpy (*this ); next (); return cpy;
263
302
}
264
303
265
- public:
266
-
267
- object_type type () const {
268
- return m_obj.type ();
269
- }
270
-
271
- size_type size () const {
272
- return m_obj.size ();
273
- }
274
-
275
- const key_type& key () const {
276
- return this ->m_key ;
277
- }
278
-
279
- const output_object_type& operator *() const {
280
- return m_obj;
281
- }
282
-
283
304
};
284
305
285
306
0 commit comments