make Session::region_name() have the same performance as std::map<std::string,uint32_t> rather than O(N^2) where N is the number of regions in a session

git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@3472 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2008-06-18 15:01:53 +00:00
parent c05d4751f9
commit 7b652d8a58
3 changed files with 43 additions and 40 deletions

View file

@ -566,7 +566,7 @@ class Session : public PBD::StatefulDestructible
sigc::signal<void,std::vector<boost::weak_ptr<AudioRegion> >& > AudioRegionsAdded;
sigc::signal<void,boost::weak_ptr<AudioRegion> > AudioRegionRemoved;
int region_name (string& result, string base = string(""), bool newlevel = false) const;
int region_name (string& result, string base = string(""), bool newlevel = false);
string new_region_name (string);
string path_from_region_name (string name, string identifier);
@ -1485,6 +1485,9 @@ class Session : public PBD::StatefulDestructible
/* REGION MANAGEMENT */
std::map<std::string,uint32_t> region_name_map;
void update_region_name_map (boost::shared_ptr<Region>);
mutable Glib::Mutex region_lock;
typedef map<PBD::ID,boost::shared_ptr<AudioRegion> > AudioRegionList;
AudioRegionList audio_regions;

View file

@ -2540,7 +2540,7 @@ Session::new_region_name (string old)
}
int
Session::region_name (string& result, string base, bool newlevel) const
Session::region_name (string& result, string base, bool newlevel)
{
char buf[16];
string subbase;
@ -2550,15 +2550,11 @@ Session::region_name (string& result, string base, bool newlevel) const
Glib::Mutex::Lock lm (region_lock);
snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
result = "region.";
result += buf;
} else {
/* XXX this is going to be slow. optimize me later */
if (newlevel) {
subbase = base;
} else {
@ -2571,45 +2567,25 @@ Session::region_name (string& result, string base, bool newlevel) const
subbase = base.substr (0, pos);
}
bool name_taken = true;
{
Glib::Mutex::Lock lm (region_lock);
cerr << "Session::region_name() searching over " << audio_regions.size() << " existing regions\n";
for (int n = 1; n < 5000; ++n) {
map<string,uint32_t>::iterator x;
int nxx = 0;
result = subbase;
snprintf (buf, sizeof (buf), ".%d", n);
result = subbase;
if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
result += ".1";
region_name_map[subbase] = 1;
} else {
x->second++;
snprintf (buf, sizeof (buf), ".%d", x->second);
result += buf;
name_taken = false;
for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i, ++nxx) {
if (i->second->name() == result) {
name_taken = true;
break;
}
}
cerr << "\tusing " << n << " for " << result << " name search ended after checking " << nxx << " regions, taken ? " << name_taken << endl;
if (!name_taken) {
break;
}
}
}
if (name_taken) {
fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
/*NOTREACHED*/
}
}
return 0;
}
@ -2661,7 +2637,6 @@ Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
if (!x.second) {
return;
}
@ -2684,7 +2659,7 @@ Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
add the region to the region list.
*/
set_dirty();
set_dirty ();
if (added) {
@ -2710,14 +2685,35 @@ Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
update_region_name_map (region);
}
if (!v.empty()) {
AudioRegionsAdded (v); /* EMIT SIGNAL */
}
}
}
void
Session::update_region_name_map (boost::shared_ptr<Region> region)
{
string::size_type last_period = region->name().find_last_of ('.');
if (last_period != string::npos && last_period < region->name().length() - 1) {
string base = region->name().substr (0, last_period);
string number = region->name().substr (last_period+1);
map<string,uint32_t>::iterator x;
/* note that if there is no number, we get zero from atoi,
which is just fine
*/
region_name_map[base] = atoi (number);
}
}
void
Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
{
@ -2731,6 +2727,10 @@ Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_regio
/* relay hidden changes */
RegionHiddenChange (region);
}
if (what_changed & NameChanged) {
update_region_name_map (region);
}
}
void

View file

@ -17,7 +17,7 @@ Onset.cpp
""")
Import('env install_prefix libraries')
vampplugs = env.Copy()
vampplugs = env.Clone()
vampplugs.Append (CPPATH='#libs/vamp-sdk/vamp', CXXFLAGS="-Ilibs/vamp-sdk")
vampplugs.Merge ([libraries['vamp'],