mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2025-02-20 12:14:55 +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(),
|
mime_full(),
|
||||||
atime(parATime),
|
atime(parATime),
|
||||||
mtime(parMTime),
|
mtime(parMTime),
|
||||||
path(abs_path),
|
|
||||||
mime_type(),
|
mime_type(),
|
||||||
mime_charset(),
|
mime_charset(),
|
||||||
size(0),
|
size(0),
|
||||||
level(parLevel),
|
level(parLevel),
|
||||||
|
path_offset(0),
|
||||||
is_directory(parIsDir),
|
is_directory(parIsDir),
|
||||||
is_symlink(parIsSymLink),
|
is_symlink(parIsSymLink),
|
||||||
unreadable(false),
|
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 {},
|
hash {},
|
||||||
abs_path(std::move(parPath)),
|
abs_path(std::move(parPath)),
|
||||||
mime_full(),
|
mime_full(),
|
||||||
atime(parATime),
|
atime(parATime),
|
||||||
mtime(parMTime),
|
mtime(parMTime),
|
||||||
path(boost::string_ref(abs_path).substr(parRelPathOffs)),
|
|
||||||
mime_type(),
|
mime_type(),
|
||||||
mime_charset(),
|
mime_charset(),
|
||||||
size(0),
|
size(0),
|
||||||
level(parLevel),
|
level(parLevel),
|
||||||
|
path_offset(parRelPathOffs),
|
||||||
is_directory(parIsDir),
|
is_directory(parIsDir),
|
||||||
is_symlink(parIsSymLink),
|
is_symlink(parIsSymLink),
|
||||||
unreadable(false),
|
unreadable(false),
|
||||||
hash_valid(false)
|
hash_valid(false)
|
||||||
{
|
{
|
||||||
|
assert(path_offset <= abs_path.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(NDEBUG)
|
#if defined(NDEBUG)
|
||||||
|
@ -81,16 +82,18 @@ namespace mchlib {
|
||||||
bool operator== ( const FileRecordData& parOther ) const;
|
bool operator== ( const FileRecordData& parOther ) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
boost::string_ref path ( void ) const { return boost::string_ref(abs_path).substr(path_offset); }
|
||||||
|
|
||||||
TigerHash hash;
|
TigerHash hash;
|
||||||
std::string abs_path;
|
std::string abs_path;
|
||||||
mime_string mime_full;
|
mime_string mime_full;
|
||||||
std::time_t atime;
|
std::time_t atime;
|
||||||
std::time_t mtime;
|
std::time_t mtime;
|
||||||
boost::string_ref path;
|
|
||||||
boost::string_ref mime_type;
|
boost::string_ref mime_type;
|
||||||
boost::string_ref mime_charset;
|
boost::string_ref mime_charset;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint16_t level;
|
uint16_t level;
|
||||||
|
uint16_t path_offset; //Relative path starting character into abs_path
|
||||||
bool is_directory;
|
bool is_directory;
|
||||||
bool is_symlink;
|
bool is_symlink;
|
||||||
bool unreadable;
|
bool unreadable;
|
||||||
|
|
|
@ -24,14 +24,14 @@
|
||||||
namespace mchlib {
|
namespace mchlib {
|
||||||
namespace implem {
|
namespace implem {
|
||||||
bool glob_matches (const FileRecordData& parData, const char* parGlob) {
|
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
|
//assert that the substring in path terminates at the same place
|
||||||
//where the one in abs_path terminates (ie: it's null-terminated).
|
//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
|
//See https://github.com/FlibbleMr/neolib/blob/master/include/neolib/string_utils.hpp
|
||||||
//for an alternative to fnmatch() (grep wildcard_match)
|
//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;
|
return not match;
|
||||||
}
|
}
|
||||||
} //namespace implem
|
} //namespace implem
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace mchlib {
|
||||||
for (auto it = parList.begin(); it != parList.end(); ++it) {
|
for (auto it = parList.begin(); it != parList.end(); ++it) {
|
||||||
assert(PathName(parEntry.abs_path) == PathName(it->abs_path).pop_right());
|
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);
|
const auto basename = mchlib::basename(curr_path);
|
||||||
if (it->is_directory) {
|
if (it->is_directory) {
|
||||||
auto cd_list = MutableSetListingView(it);
|
auto cd_list = MutableSetListingView(it);
|
||||||
|
|
|
@ -99,14 +99,14 @@ namespace mchlib {
|
||||||
{
|
{
|
||||||
assert(parBasePath);
|
assert(parBasePath);
|
||||||
assert(m_base_path or m_current == m_end);
|
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);
|
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
|
//Look for the point where the children of this entry start
|
||||||
while (
|
while (
|
||||||
m_current != m_end and (
|
m_current != m_end and (
|
||||||
m_current->level + m_level_offset == m_base_path->atom_count() or
|
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);
|
assert(m_base_path);
|
||||||
++m_current;
|
++m_current;
|
||||||
|
@ -157,13 +157,13 @@ namespace mchlib {
|
||||||
|
|
||||||
template <bool Const>
|
template <bool Const>
|
||||||
void DirIterator<Const>::increment() {
|
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 {
|
do {
|
||||||
++m_current;
|
++m_current;
|
||||||
} while(
|
} while(
|
||||||
m_current != m_end and
|
m_current != m_end and
|
||||||
m_current->level + m_level_offset == m_base_path->atom_count() + 1 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()));
|
assert(std::equal(m_list.begin(), m_list.end(), SetListing(ListType(m_list), true).sorted_list().begin()));
|
||||||
}
|
}
|
||||||
if (not m_list.empty()) {
|
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() {
|
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);
|
return SetListingView<false>(m_list.begin(), m_list.end(), offs, m_base_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetListingView<true> SetListing::make_view() const {
|
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);
|
return SetListingView<true>(m_list.begin(), m_list.end(), offs, m_base_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetListingView<true> SetListing::make_cview() const {
|
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);
|
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)
|
m_level_offset(parIter.m_level_offset)
|
||||||
{
|
{
|
||||||
if (m_begin != m_end) {
|
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)
|
m_level_offset(parLevelOffset)
|
||||||
{
|
{
|
||||||
if (m_begin != m_end) {
|
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 != "/") {
|
if (parItem.abs_path.size() != 1 or parItem.abs_path != "/") {
|
||||||
parItem.abs_path = std::string("/") + 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);";
|
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);";
|
||||||
|
|
||||||
const auto& itm = parData[z];
|
const auto& itm = parData[z];
|
||||||
assert(itm.path.data());
|
assert(itm.path().data());
|
||||||
conn.query(query,
|
conn.query(query,
|
||||||
(itm.path.empty() ? empty_path_string : itm.path),
|
(itm.path().empty() ? empty_path_string : itm.path()),
|
||||||
tiger_to_string(itm.hash),
|
tiger_to_string(itm.hash),
|
||||||
itm.level,
|
itm.level,
|
||||||
new_group_id,
|
new_group_id,
|
||||||
|
|
Loading…
Add table
Reference in a new issue