mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2025-02-19 12:04:54 +00:00
Crash fix - make path on the fly
Newer versions of gcc have a small string optimizations that makes moving FileRecordData objects behave incorrectly. When a small string is moved, string_refs into it become invalid. Making a path on the fly using the path() method also has the side effect of making FileRecordData smaller in size.
This commit is contained in:
parent
21c5b3efcb
commit
8c03ba15bc
5 changed files with 24 additions and 21 deletions
|
@ -39,11 +39,11 @@ namespace mchlib {
|
|||
mime_full(),
|
||||
atime(parATime),
|
||||
mtime(parMTime),
|
||||
path(abs_path),
|
||||
mime_type(),
|
||||
mime_charset(),
|
||||
size(0),
|
||||
level(parLevel),
|
||||
path_offset(0),
|
||||
is_directory(parIsDir),
|
||||
is_symlink(parIsSymLink),
|
||||
unreadable(false),
|
||||
|
@ -51,22 +51,23 @@ namespace mchlib {
|
|||
{
|
||||
}
|
||||
|
||||
FileRecordData ( std::string&& parPath, std::size_t parRelPathOffs, std::time_t parATime, std::time_t parMTime, uint16_t parLevel, bool parIsDir, bool parIsSymLink ) :
|
||||
FileRecordData ( std::string&& parPath, uint16_t parRelPathOffs, std::time_t parATime, std::time_t parMTime, uint16_t parLevel, bool parIsDir, bool parIsSymLink ) :
|
||||
hash {},
|
||||
abs_path(std::move(parPath)),
|
||||
mime_full(),
|
||||
atime(parATime),
|
||||
mtime(parMTime),
|
||||
path(boost::string_ref(abs_path).substr(parRelPathOffs)),
|
||||
mime_type(),
|
||||
mime_charset(),
|
||||
size(0),
|
||||
level(parLevel),
|
||||
path_offset(parRelPathOffs),
|
||||
is_directory(parIsDir),
|
||||
is_symlink(parIsSymLink),
|
||||
unreadable(false),
|
||||
hash_valid(false)
|
||||
{
|
||||
assert(path_offset <= abs_path.size());
|
||||
}
|
||||
|
||||
#if defined(NDEBUG)
|
||||
|
@ -81,16 +82,18 @@ namespace mchlib {
|
|||
bool operator== ( const FileRecordData& parOther ) const;
|
||||
#endif
|
||||
|
||||
boost::string_ref path ( void ) const { return boost::string_ref(abs_path).substr(path_offset); }
|
||||
|
||||
TigerHash hash;
|
||||
std::string abs_path;
|
||||
mime_string mime_full;
|
||||
std::time_t atime;
|
||||
std::time_t mtime;
|
||||
boost::string_ref path;
|
||||
boost::string_ref mime_type;
|
||||
boost::string_ref mime_charset;
|
||||
uint64_t size;
|
||||
uint16_t level;
|
||||
uint16_t path_offset; //Relative path starting character into abs_path
|
||||
bool is_directory;
|
||||
bool is_symlink;
|
||||
bool unreadable;
|
||||
|
|
|
@ -24,14 +24,14 @@
|
|||
namespace mchlib {
|
||||
namespace implem {
|
||||
bool glob_matches (const FileRecordData& parData, const char* parGlob) {
|
||||
assert(parData.path.data());
|
||||
assert(parData.path().data());
|
||||
//assert that the substring in path terminates at the same place
|
||||
//where the one in abs_path terminates (ie: it's null-terminated).
|
||||
assert(parData.path == std::string(parData.path.data()));
|
||||
assert(parData.path() == std::string(parData.path().data()));
|
||||
|
||||
//See https://github.com/FlibbleMr/neolib/blob/master/include/neolib/string_utils.hpp
|
||||
//for an alternative to fnmatch() (grep wildcard_match)
|
||||
const int match = fnmatch(parGlob, parData.path.data(), FNM_PATHNAME);
|
||||
const int match = fnmatch(parGlob, parData.path().data(), FNM_PATHNAME);
|
||||
return not match;
|
||||
}
|
||||
} //namespace implem
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace mchlib {
|
|||
for (auto it = parList.begin(); it != parList.end(); ++it) {
|
||||
assert(PathName(parEntry.abs_path) == PathName(it->abs_path).pop_right());
|
||||
|
||||
PathName curr_path(it->path);
|
||||
PathName curr_path(it->path());
|
||||
const auto basename = mchlib::basename(curr_path);
|
||||
if (it->is_directory) {
|
||||
auto cd_list = MutableSetListingView(it);
|
||||
|
|
|
@ -99,14 +99,14 @@ namespace mchlib {
|
|||
{
|
||||
assert(parBasePath);
|
||||
assert(m_base_path or m_current == m_end);
|
||||
assert(m_current == m_end or m_base_path->atom_count() == PathName(m_current->path).atom_count() + parLevelOffset);
|
||||
assert(m_current == m_end or m_base_path->atom_count() == PathName(m_current->path()).atom_count() + parLevelOffset);
|
||||
assert(m_current == m_end or m_base_path->atom_count() == m_current->level + m_level_offset);
|
||||
|
||||
//Look for the point where the children of this entry start
|
||||
while (
|
||||
m_current != m_end and (
|
||||
m_current->level + m_level_offset == m_base_path->atom_count() or
|
||||
*m_base_path != PathName(m_current->path).pop_right()
|
||||
*m_base_path != PathName(m_current->path()).pop_right()
|
||||
)) {
|
||||
assert(m_base_path);
|
||||
++m_current;
|
||||
|
@ -157,13 +157,13 @@ namespace mchlib {
|
|||
|
||||
template <bool Const>
|
||||
void DirIterator<Const>::increment() {
|
||||
assert(PathName(m_current->path).pop_right() == *m_base_path);
|
||||
assert(PathName(m_current->path()).pop_right() == *m_base_path);
|
||||
do {
|
||||
++m_current;
|
||||
} while(
|
||||
m_current != m_end and
|
||||
m_current->level + m_level_offset == m_base_path->atom_count() + 1 and
|
||||
*m_base_path != PathName(m_current->path).pop_right()
|
||||
*m_base_path != PathName(m_current->path()).pop_right()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ namespace mchlib {
|
|||
assert(std::equal(m_list.begin(), m_list.end(), SetListing(ListType(m_list), true).sorted_list().begin()));
|
||||
}
|
||||
if (not m_list.empty()) {
|
||||
m_base_path.reset(new PathName(m_list.front().path));
|
||||
m_base_path.reset(new PathName(m_list.front().path()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,17 +289,17 @@ namespace mchlib {
|
|||
}
|
||||
|
||||
SetListingView<false> SetListing::make_view() {
|
||||
const auto offs = (m_list.empty() ? 0 : PathName(m_list.front().path).atom_count());
|
||||
const auto offs = (m_list.empty() ? 0 : PathName(m_list.front().path()).atom_count());
|
||||
return SetListingView<false>(m_list.begin(), m_list.end(), offs, m_base_path);
|
||||
}
|
||||
|
||||
SetListingView<true> SetListing::make_view() const {
|
||||
const auto offs = (m_list.empty() ? 0 : PathName(m_list.front().path).atom_count());
|
||||
const auto offs = (m_list.empty() ? 0 : PathName(m_list.front().path()).atom_count());
|
||||
return SetListingView<true>(m_list.begin(), m_list.end(), offs, m_base_path);
|
||||
}
|
||||
|
||||
SetListingView<true> SetListing::make_cview() const {
|
||||
const auto offs = (m_list.empty() ? 0 : PathName(m_list.front().path).atom_count());
|
||||
const auto offs = (m_list.empty() ? 0 : PathName(m_list.front().path()).atom_count());
|
||||
return SetListingView<true>(m_list.begin(), m_list.end(), offs, m_base_path);
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,7 @@ namespace mchlib {
|
|||
m_level_offset(parIter.m_level_offset)
|
||||
{
|
||||
if (m_begin != m_end) {
|
||||
m_base_path.reset(new PathName(m_begin->path));
|
||||
m_base_path.reset(new PathName(m_begin->path()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,7 +323,7 @@ namespace mchlib {
|
|||
m_level_offset(parLevelOffset)
|
||||
{
|
||||
if (m_begin != m_end) {
|
||||
m_base_path.reset(new PathName(m_begin->path));
|
||||
m_base_path.reset(new PathName(m_begin->path()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace din {
|
|||
if (parItem.abs_path.size() != 1 or parItem.abs_path != "/") {
|
||||
parItem.abs_path = std::string("/") + parItem.abs_path;
|
||||
}
|
||||
parItem.path = boost::string_ref(parItem.abs_path).substr(1);
|
||||
parItem.path_offset = 1;
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -125,9 +125,9 @@ namespace din {
|
|||
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);";
|
||||
|
||||
const auto& itm = parData[z];
|
||||
assert(itm.path.data());
|
||||
assert(itm.path().data());
|
||||
conn.query(query,
|
||||
(itm.path.empty() ? empty_path_string : itm.path),
|
||||
(itm.path().empty() ? empty_path_string : itm.path()),
|
||||
tiger_to_string(itm.hash),
|
||||
itm.level,
|
||||
new_group_id,
|
||||
|
|
Loading…
Add table
Reference in a new issue