Carsten Neumann wrote:
> Hi,
>
> I'm currently working on ticket #124 and thought I'll let you know what
> I intend to do, so you can stop me from introducing any unmaintainable
> garbage ;)
> My current design should be able to deliver the same features as the
> current OSB loader, but without the static member variables. I do not
> have much code yet, just enough to convince myself that the rest can be
> done in a similar fashion (I've attached a file with sketches of the
> main classes).
>
> With the current NFIO classes there is one for each FieldContainer that
> requires special handling and one (NFIOGeneric) that handles all others.
> Global state of the loader is stored in static member variables so that
> the individual objects have access to it. Loader objects are created by
> NFIOFactory which chooses the proper one from the type name of the
> container to load.
> The basics will remain quite similar, but there'll be the notion of a
> root element that reads/writes the file header, holds the global state
> and drives the i/o process. Every i/o object will hold a pointer to the
> root element. The i/o objects should be lightweight enough to allow
> rapid creation, but maybe the factory will need to be outfitted with a
> pool or use a special allocator.
>
> I'm aware this is a quite terse description, but I'll be happy to give
> more details if you are interested, so comments, ideas and questions are
> very welcome.
This sounds reasonable to me and describes similar thoughts I had when I
looked into that code.
A couple of ideas that may be worth thinking about:
- Using boost::shared_ptr's for the backreferences. I would very much
like to see the memory handling in OpenSG become a little more robust.
One way that I have used in my own code is to use boost::shared_ptr and
boost::weak_ptr to make sure everything is collected correctly. This
may be useful here to make sure nothing gets deleted early.
- Is there any way to look at the NFIOElement's as implementations of a
strategy pattern that simply take a reference to a per-file global
state. In more detail.
What if the factory held a set of lightweight strategy objects. One
instance per element type that needs custom handling. When a file needs
to be written or read, the system creates a file-state object that track
the global state needed for that single IO. Then as the process
progresses the read/write algorithm core (possibly implemented inside
the state tracking object) asks the factory object for the correct
strategy to use for the encountered fc type. The factory will either
return the generic strategy or a custom strategy. Then the algorithm
still calls the read/postRead/preWrite/write methods but does so with an
additional parameter, namely the file-state object.
This would remove the threading issues because all data would be stored
in the file-state object and it would make it so only one instance of
the strategies for each custom fc type would ever need to be created.
The strategies themselves would be thread-safe and re-entrant (ie.
multiple read/writes could use the same strategy in parallel) because
all the state would be held in the file-state object.
Note: I have not taken a look at the NFIO code based on this idea. I am
just thinking of this from memory. So feel free to ignore the idea if
it can't be realized with the current codebase.
Thanks for taking on this challenge. It is very nice to have someone
investing so much time in the 2.0 code.
-Allen
>
> Cheers,
> Carsten
>
>
> ------------------------------------------------------------------------
>
>
> // Base for elments
> class NFIOElementBase
> {
> public:
> virtual void read (const std::string &typeName) = 0;
> virtual void postRead( void ) = 0;
>
> virtual void preWrite(const FieldContainerPtr &fc) = 0;
> virtual void write (const FieldContainerPtr &fc) = 0;
>
> protected:
> struct PtrFieldInfo
> {
> FieldContainerPtr _fc;
> UInt32 _fieldId;
> std::vector<UInt32> _ptrIds;
> };
>
> private:
> FieldContainerPtr _container; // container read by this element
> NFIORootElement *_rootElement; // root
> UInt16 _version; // version supported by this element
> };
>
> // Holds global state for i/o, drives the reading/writing process.
> class NFIORootElement : public NFIOElementBase
> {
> public:
> // read file header - trigger reading of FCs in file - fill _elements
> virtual void read (const std::string &typeName);
>
> // call postRead for all _elements - afterwards map file ptr ids to real
> ptrs
> virtual void postRead( void );
>
> // count/determine FCs that need to be written - fill _writeFCList
> virtual void preWrite(const FieldContainerPtr &fc);
>
> // write out containers
> virtual void write (const FieldContainerPtr &fc);
>
> protected:
> BinaryReadHandler *_readHandler;
> BinaryWriteHandler *_writeHandler;
>
> NFIOOptions _options;
> std::list<NFIOElementBase *> _elements;
>
> UInt16 _readHeaderVersion;
> std::map <UInt32, UInt32> _readIdMap;
> std::list<PtrFieldInfo > _readPtrFields;
>
> std::list<FieldContainerPtr> _writeFCList;
> std::set <UInt32 > _writeIdSet;
> };
>
> class NFIOCommonElement : public NFIOElementBase
> {
> // helper methods that are useful for implementing a specific loader
> };
>
> // loader for all FCs that do not need special handling
> class NFIOGeneric : public NFIOCommonElement
> {
> public:
> virtual void read (const std::string &typeName);
> virtual void postRead( void );
>
> virtual void preWrite(const FieldContainerPtr &fc);
> virtual void write (const FieldContainerPtr &fc);
> };
>
>
> // Factory singleton for the loader/writer elements - should probably use
> // some sort of pool or special purpose allocator to allow rapid creation of
> // the objects.
> class NFIOFactory
> {
> // singleton access
> static NFIOFactory *the(void);
>
> NFIOElementBase *acquire(const std::string &typeName, NFIORootElement
> *root);
> void release(NFIOElementBase *elem);
> };
>
>
> ------------------------------------------------------------------------
>
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys - and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Opensg-core mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/opensg-core
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Opensg-core mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-core