Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Aug 25, 2021. It is now read-only.

Commit b7057f5

Browse files
committed
Implemented simple test which loops over the loose objects and queries
object information. Fixed a few bugs on the way. Now its time to implement the core, which is the stream that can handle dynamic compression/decompression, all suitably abstracted to allow others to easily create different streams without noticable performance penalty.
1 parent 22471c0 commit b7057f5

File tree

4 files changed

+75
-44
lines changed

4 files changed

+75
-44
lines changed

src/gtl/db/odb.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ class odb_base
7474
{
7575
size_t out = 0;
7676
for (; start != end; ++start, ++out);
77-
// out is one too high as it was increment before we figured out that end was already reached.
78-
return out-1;
77+
return out;
7978
}
8079

8180
//! @}

src/gtl/db/odb_loose.hpp

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <gtl/db/odb_object.hpp>
77
#include <boost/iostreams/filter/zlib.hpp>
88
#include <boost/filesystem.hpp>
9+
#include <cstring>
910

1011
GTL_HEADER_BEGIN
1112
GTL_NAMESPACE_BEGIN
@@ -64,11 +65,18 @@ class odb_loose_output_object
6465
typedef typename traits_type::object_type object_type;
6566
typedef odb_loose_output_object this_type;
6667

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+
6775
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;
7280

7381
public:
7482

@@ -100,12 +108,16 @@ class odb_loose_output_object
100108
}
101109

102110
object_type type() const {
103-
// todo init info
111+
if (!m_initialized){
112+
init();
113+
}
104114
return m_obj_type;
105115
}
106116

107117
size_type size() const {
108-
// todo initialize
118+
if (!m_initialized){
119+
init();
120+
}
109121
return m_size;
110122
}
111123

@@ -120,6 +132,7 @@ class odb_loose_output_object
120132

121133
//! modifyable version of our internal path
122134
path_type& path() {
135+
m_initialized = false; // could change the path, and usually does !
123136
return m_path;
124137
}
125138

@@ -138,52 +151,78 @@ class loose_accessor : public odb_accessor<ObjectTraits>
138151
typedef typename traits_type::key_type key_type;
139152
typedef typename traits_type::size_type size_type;
140153
typedef typename traits_type::object_type object_type;
154+
typedef typename db_traits_type::path_type path_type;
141155
typedef loose_accessor<traits_type, db_traits_type> this_type;
142156

143157
protected:
144-
key_type m_key;
145158
mutable output_object_type m_obj;
146159

147160
protected:
148161
//! Default constructor, only for derived types
149-
loose_accessor() {}
162+
loose_accessor(){}
150163

151164
public:
152165
//! Initialize this instance with a key to operate upon.
153166
//! 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)
156169
{}
157170

171+
loose_accessor(const this_type& rhs)
172+
: m_obj(rhs.m_obj)
173+
{}
174+
175+
loose_accessor(this_type&&) = default;
176+
158177
//! Equality comparison of compatible iterators
159178
inline bool operator==(const this_type& rhs) const {
160-
return m_key == rhs.m_key;
179+
return m_obj == rhs.m_obj;
161180
}
162181

163182
//! Inequality comparison
164183
inline bool operator!=(const this_type& rhs) const {
165-
return !(m_key == rhs.m_key);
184+
return !(m_obj == rhs.m_obj);
166185
}
167186

168187
//! allows access to the actual input object
169188
inline const output_object_type& operator*() const {
170-
// initialize if required
171189
return m_obj;
172190
}
173191

174192
//! allow -> semantics
175193
inline const output_object_type* operator->() const {
176-
// initialize if required
177194
return &m_obj;
178195
}
179196

180197
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);
183221
}
184222

185223
};
186224

225+
187226
/** \brief iterator for all loose objects in the database.
188227
* It iterates folders and files within these folders until the folder interation is depleted.
189228
* \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>
203242

204243
protected:
205244
boost::filesystem::recursive_directory_iterator m_iter;
206-
output_object_type m_obj; // object at current iteration
207245

208246
protected:
209247
//! increment our iterator to the next object file
@@ -221,8 +259,7 @@ class loose_forward_iterator : public loose_accessor<ObjectTraits, Traits>
221259
if (path.filename().size()/2 == key_type::hash_len - db_traits_type::num_prefix_characters &&
222260
(*(--(--path.end()))).size()/2 == db_traits_type::num_prefix_characters)
223261
{
224-
m_obj = output_object_type(path);
225-
std::cerr << "Found one: " << path.filename() << std::endl;
262+
this->m_obj.path() = path;
226263
break;
227264
}
228265
}
@@ -232,18 +269,20 @@ class loose_forward_iterator : public loose_accessor<ObjectTraits, Traits>
232269
public:
233270
loose_forward_iterator(const path_type& root)
234271
: m_iter(root)
235-
{}
272+
{next();}
236273

237274
//! default constructor, used as end iterator
238275
loose_forward_iterator()
239276
{}
240277

241278
//! copy constructor
242279
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)
245282
{}
246283

284+
loose_forward_iterator(this_type&&) = default;
285+
247286
//! Equality comparison of compatible iterators
248287
inline bool operator==(const this_type& rhs) const {
249288
return m_iter == rhs.m_iter;
@@ -262,24 +301,6 @@ class loose_forward_iterator : public loose_accessor<ObjectTraits, Traits>
262301
this_type cpy(*this); next(); return cpy;
263302
}
264303

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-
283304
};
284305

285306

src/gtl/util.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ CharType fromhex(const CharType* c2)
112112
hc[1] = std::toupper(c2[1]);
113113

114114
CharType out;
115-
out = map[(uchar)c2[0]] << 4;
116-
out |= map[(uchar)c2[1]];
115+
out = map[(uchar)hc[0]] << 4;
116+
out |= map[(uchar)hc[1]];
117117

118118
return out;
119119
}

test/git/db/lib_odb_test.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ using namespace git;
2424
const char* const phello = "hello";
2525
const size_t lenphello = 5;
2626
const std::string hello_hex_sha("AAF4C61DDCC5E8A2DABEDE0F3B482CD9AEA9434D");
27+
const std::string hello_hex_sha_lc("aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d");
2728
const std::string null_hex_sha("0000000000000000000000000000000000000000");
2829

2930

@@ -173,6 +174,9 @@ BOOST_AUTO_TEST_CASE(lib_sha1_facility)
173174
BOOST_CHECK(s[0] == 'a');
174175
BOOST_CHECK(s[1] == 'b');
175176

177+
// upper/lower case hex input yields same results
178+
BOOST_REQUIRE(SHA1(hello_hex_sha) == SHA1(hello_hex_sha_lc));
179+
176180

177181
// GENERATOR
178182
////////////
@@ -356,4 +360,11 @@ BOOST_FIXTURE_TEST_CASE(loose_db_test, GitLooseODBFixture)
356360
{
357361
LooseODB lodb(rw_dir());
358362
BOOST_REQUIRE(lodb.count() == 10);
363+
364+
auto end = lodb.end();
365+
uint count=0;
366+
for (auto it=lodb.begin(); it != end; ++it, ++count){
367+
cerr << "object " << count << " at " << it->path() << " " << it.key() << " " << it->type() << " " << it->size() << endl;
368+
}
369+
359370
}

0 commit comments

Comments
 (0)