#
# patch "ChangeLog"
# from [e9de117a2044926f443013af7951cbe6069c62ae]
# to [647015eb14f585af944198b25fbd7699b42cee62]
#
# patch "inodeprint.cc"
# from [88e4c413bf8b723e01274e7377ab3ce8bfdadb0c]
# to [3e50716f49cc55772d0473f5de61ca7891f980b2]
#
# patch "manifest.cc"
# from [13650d15c6b7fde18fb7018c68ebbf2e82d2d125]
# to [4710b6b5b9c464e22894e8408c71d6afdd1c5f3a]
#
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,11 @@
+2005-04-24 Nathaniel Smith
+
+ * manifest.cc (build_restricted_manifest_map): Careful to only
+ stat things once on the inodeprints fast-path.
+ (read_manifest_map): Hand-code a parser, instead of using
+ boost::regex.
+ * inodeprint.cc (read_inodeprint_map): Likewise.
+
2005-04-23 Derek Scherger
* app_state.cc:
--- inodeprint.cc
+++ inodeprint.cc
@@ -18,33 +18,38 @@
#include "inodeprint.hh"
#include "sanity.hh"
#include "platform.hh"
+#include "constants.hh"
// this file defines the inodeprint_map structure, and some operations on it.
// it is currently heavily based on manifest.cc.
// reading inodeprint_maps
-struct
-add_to_inodeprint_map
-{
- inodeprint_map & ipm;
- explicit add_to_inodeprint_map(inodeprint_map & ipm) : ipm(ipm) {}
- bool operator()(boost::match_results const & res)
- {
- std::string ident(res[1].first, res[1].second);
- std::string path(res[2].first, res[2].second);
- file_path pth(path);
- ipm.insert(inodeprint_entry(pth, hexenc(ident)));
- return true;
- }
-};
-
void
read_inodeprint_map(data const & dat,
inodeprint_map & ipm)
{
- boost::regex expr("^([[:xdigit:]]{40}) ([^[:space:]].*)$");
- boost::regex_grep(add_to_inodeprint_map(ipm), dat(), expr, boost::match_not_dot_newline);
+ std::string::size_type pos = 0;
+ while (pos != dat().size())
+ {
+ // whenever we get here, pos points to the beginning of a inodeprint
+ // line
+ // inodeprint file has 40 characters hash, then 2 characters space, then
+ // everything until next \n is filename.
+ std::string ident = dat().substr(pos, constants::idlen);
+ std::string::size_type file_name_begin = pos + constants::idlen + 2;
+ pos = dat().find('\n', file_name_begin);
+ std::string file_name;
+ if (pos == std::string::npos)
+ file_name = dat().substr(file_name_begin);
+ else
+ file_name = dat().substr(file_name_begin, pos - file_name_begin);
+ ipm.insert(inodeprint_entry(file_path(file_name),
+ hexenc(ident)));
+ // skip past the '\n'
+ ++pos;
+ }
+ return;
}
// writing inodeprint_maps
--- manifest.cc
+++ manifest.cc
@@ -23,6 +23,7 @@
#include "sanity.hh"
#include "inodeprint.hh"
#include "platform.hh"
+#include "constants.hh"
// this file defines the class of manifest_map objects, and various comparison
// and i/o functions on them. a manifest specifies exactly which versions
@@ -78,10 +79,11 @@
for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i)
{
- bool exists = file_exists(*i);
bool included = app.restriction_includes(*i);
- if (included && exists)
+ // first, make a try to see if we have a current inodeprint. if we do,
+ // we skip the rest of this block to go around the loop again.
+ if (included)
{
// compute the current sha1 id for included files
// we might be able to avoid it, if we have an inode fingerprint...
@@ -99,7 +101,14 @@
continue;
}
}
- // ...ah, well, no good fingerprint, just check directly.
+ }
+ // ...ah, well, no good inodeprint, let's do proper checking.
+ // note that we carefully do not call file_exists() until _after_ we've
+ // given inodeprints a chance; this halves the number of stat calls in a
+ // typical large tree using inodeprints.
+ bool exists = file_exists(*i);
+ if (included && exists)
+ {
hexenc ident;
calculate_ident(*i, ident, app.lua);
m_new.insert(manifest_entry(*i, file_id(ident)));
@@ -127,27 +136,30 @@
// reading manifest_maps
-struct
-add_to_manifest_map
-{
- manifest_map & man;
- explicit add_to_manifest_map(manifest_map & m) : man(m) {}
- bool operator()(match_results const & res)
- {
- std::string ident(res[1].first, res[1].second);
- std::string path(res[2].first, res[2].second);
- file_path pth(path);
- man.insert(manifest_entry(pth, hexenc(ident)));
- return true;
- }
-};
-
void
read_manifest_map(data const & dat,
manifest_map & man)
{
- regex expr("^([[:xdigit:]]{40}) ([^[:space:]].*)$");
- regex_grep(add_to_manifest_map(man), dat(), expr, match_not_dot_newline);
+ std::string::size_type pos = 0;
+ while (pos != dat().size())
+ {
+ // whenever we get here, pos points to the beginning of a manifest
+ // line
+ // manifest file has 40 characters hash, then 2 characters space, then
+ // everything until next \n is filename.
+ std::string ident = dat().substr(pos, constants::idlen);
+ std::string::size_type file_name_begin = pos + constants::idlen + 2;
+ pos = dat().find('\n', file_name_begin);
+ std::string file_name;
+ if (pos == std::string::npos)
+ file_name = dat().substr(file_name_begin);
+ else
+ file_name = dat().substr(file_name_begin, pos - file_name_begin);
+ man.insert(manifest_entry(file_path(file_name), hexenc(ident)));
+ // skip past the '\n'
+ ++pos;
+ }
+ return;
}
void