Hello Michael,
On 07/13/2011 05:43 AM, Michael Raab wrote:
some days ago I thought it would be a good idea to call
Changelist::compactChanged() on our current changelist after loading a huge
chunk of data to assure to transmit as less data as possible to our render
servers.
Today I observed some weired synchronization problems. After some debugging it
seems that those were caused by the compactChanged() function call.
I don't know what the original intention of this function was, but it seems to
lose very relevant information. For example all information about destroyed
fieldcontainers disappear after compact().
hmm, looking at the function there are indeed a few problems with it. It
seems to be written with the implicit assumption that the complete
change history is contained in the CL that is being compacted:
1) it drops add/subrefs for containers that don't have create entry
2) it drops destroys for containers that don't have a create entry [1]
3) it looses all changed records and replaces them with ones that mark
all fields changed for created containers (i.e. entries for containers
that are only changed are lost).
The attached patch is an attempt to remove this implicit assumption, but
it does not fix 3) above (I just noticed it while writing this mail).
Cheers,
Carsten
[1] under the assumption of complete history it is ok to end up with no
destroy records if the corresponding create record is deleted (which is
what used to happen).
Index: Source/System/FieldContainer/OSGChangeList.cpp
===================================================================
RCS file:
/cvsroot/opensg/OpenSG/Source/System/FieldContainer/OSGChangeList.cpp,v
retrieving revision 1.14
diff -u -r1.14 OSGChangeList.cpp
--- Source/System/FieldContainer/OSGChangeList.cpp 13 Jan 2010 15:19:58
-0000 1.14
+++ Source/System/FieldContainer/OSGChangeList.cpp 13 Jul 2011 18:48:57
-0000
@@ -355,59 +355,136 @@
return _max_changed_size;
}
+namespace
+{
+ struct CLInfo
+ {
+ explicit CLInfo(Int32 dRC = 0, bool c = false, bool d = false) :
+ deltaRC(dRC),
+ create (c ),
+ destroy(d )
+ {
+ }
+
+ Int32 deltaRC;
+ bool create;
+ bool destroy;
+ };
+}
+
void ChangeList::compactChanged(void)
{
- std::map<UInt32, UInt32> clStore;
+ typedef std::map<UInt32, CLInfo> CLMap;
+
+ CLMap clMap;
// created
for(ChangeList::idrefd_const_iterator i = beginCreated(); i !=
endCreated(); ++i)
{
- std::map<UInt32, UInt32>::iterator ci = clStore.find(*i);
- if(ci == clStore.end())
- clStore.insert(std::pair<UInt32, UInt32>(*i, 0));
+ CLMap::iterator ci = clMap.find(*i);
+ if(ci == clMap.end())
+ clMap.insert(CLMap::value_type(*i, CLInfo(0, true)));
}
// addRef
for(ChangeList::idrefd_const_iterator i = beginAddRefd(); i !=
endAddRefd(); ++i)
{
- std::map<UInt32, UInt32>::iterator ci = clStore.find(*i);
- if(ci != clStore.end())
- (*ci).second++;
- //else
- // FWARNING(("Called addRef on a not created fieldcontainer!\n"));
+ CLMap::iterator ci = clMap.find(*i);
+ if(ci != clMap.end())
+ {
+ (*ci).second.deltaRC += 1;
+ }
+ else
+ {
+ clMap.insert(CLMap::value_type(*i, CLInfo(1)));
+ }
}
// subRef
for(ChangeList::idrefd_const_iterator i = beginSubRefd(); i !=
endSubRefd(); ++i)
{
- std::map<UInt32, UInt32>::iterator ci = clStore.find(*i);
- if(ci != clStore.end())
- (*ci).second--;
- //else
- // FWARNING(("Called subRef on a not created fieldcontainer!\n"));
+ CLMap::iterator ci = clMap.find(*i);
+ if(ci != clMap.end())
+ {
+ (*ci).second.deltaRC -+ 1;
+ }
+ else
+ {
+ clMap.insert(CLMap::value_type(*i, CLInfo(-1)));
+ }
+
}
// destroyed
for(ChangeList::idrefd_const_iterator i = beginDestroyed(); i !=
endDestroyed(); ++i)
{
- std::map<UInt32, UInt32>::iterator ci = clStore.find(*i);
- if(ci != clStore.end())
- clStore.erase(ci);
+ CLMap::iterator ci = clMap.find(*i);
+ if(ci != clMap.end())
+ {
+ if((*ci).second.create == true)
+ {
+ clMap.erase(ci);
+ }
+ else
+ {
+ clMap.insert(CLMap::value_type(*i, CLInfo(0, false, true)));
+ }
+ }
+ else
+ {
+ clMap.insert(CLMap::value_type(*i, CLInfo(0, false, true)));
+ }
}
clearAll();
- for(std::map<UInt32, UInt32>::iterator i = clStore.begin();i !=
clStore.end(); ++i)
+ for(CLMap::iterator i = clMap.begin(); i != clMap.end(); ++i)
{
- UInt32 id = (*i).first;
+ UInt32 id = (*i).first;
FieldContainerPtr fc = FieldContainerFactory::the()->getContainer(id);
+
if(fc != NullFC)
{
- addCreated(id);
- for(UInt32 j=0;j<(*i).second;++j)
- addAddRefd(fc);
+ if((*i).second.create == true)
+ {
+ addCreated(id);
+ }
+
+ if((*i).second.deltaRC > 0)
+ {
+ for(Int32 j = 0; j < (*i).second.deltaRC; ++j)
+ addAddRefd(fc);
+ }
+ else if((*i).second.deltaRC < 0)
+ {
+ for(Int32 j = 0; j > (*i).second.deltaRC; --j)
+ addSubRefd(fc);
+ }
+
+ if((*i).second.destroy == true)
+ {
+ FWARNING(("ChangeList::compactChanged: "
+ "FC for id [%u] is NOT NulLFC, but CL contains "
+ "destoy entry.\n", id));
+
+ addDestroyed(id);
+ }
+
addChanged(fc, FieldBits::AllFields);
}
+ else
+ {
+ if((*i).second.destroy == true)
+ {
+ addDestroyed(id);
+ }
+ else
+ {
+ FWARNING(("ChangeList::compactChanged: "
+ "FC for id [%u] is NulLFC, but CL contains "
+ "no destoy entry.\n", id));
+ }
+ }
}
}
------------------------------------------------------------------------------
AppSumo Presents a FREE Video for the SourceForge Community by Eric
Ries, the creator of the Lean Startup Methodology on "Lean Startup
Secrets Revealed." This video shows you how to validate your ideas,
optimize your ideas and identify your business strategy.
http://p.sf.net/sfu/appsumosfdev2dev
_______________________________________________
Opensg-users mailing list
Opensg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensg-users