==========================================================================
An easier iteration API for Swamp
==========================================================================
:Authors: Benja Fallenstein
:Created: 2003-09-22
:Status: Current
:Scope: Minor
:Type: Interface
:Affect-PEGs: swamp_rdf_api--tjl
As explained in ``swamp_easier--benja``, Swamp must become
easier to use. One problem to solve is that iterating
through triples isn't as easy as it should be, particularly
when you want to iterate e.g. through all triples with
a particular predicate, with any subject and object.
This PEG proposes a way to iterate through a *set of triples*,
without creating a Java object for each triple, by having
a special iterator-like object that has three nodes
at each iteration step (RDF subject, predicate, and object).
This would be returned by the old ``findN_XXX()`` or the proposed
``get()`` methods (see other PEG).
.. Issues
======
Changes
=======
We shall use an iterator-like object, ``Triples``, with the
following API::
Object sub, pred, ob;
(These are ``null`` when the object hasn't been
initialized, i.e., ``next()`` hasn't been called yet.)
/** Advance to the next triple. */
void next();
/** Whether there are any more triples to iterate through. */
boolean hasNext();
/** Indicate that this Triples
object won't be
* used any more.
* This shall only be called by the code that has requested
* this object from ConstGraph
(through
* .get()
). It's purpose is to tell the
* ConstGraph
that it can be re-used for the
* next get()
; ConstGraph
can then
* cache Triples
objects, making life easier
* for the garbage collector.
*
* Calling this method is not obligatory. (If you don't, * this object will be garbage-collected normally.) */ void free(); boolean loop() { if(hasNext()) { next(); return true; } else { free(); return false; } } The purpose of ``loop()`` is to enable the common loop pattern, :: for(Triples t = graph.get(...); t.loop();) { // ... } which would otherwise have to be written as:: Triples t; for(t = graph.get(...); t.hasNext(); t.next()) { // ... } t.free(); This isn't just harder to read, it also scopes ``t`` wrongly. With the ``loop()`` pattern, the scope of ``t`` is the body of the loop, which is exactly the code executed before ``free()`` is called.