Marshall Schor wrote:
Marshall Schor wrote:
Adam Lally wrote:
On 5/13/07, Marshall Schor <[EMAIL PROTECTED]> wrote:
Before:
---------------------------------------------------
MyAnnotation x = new MyAnnotation(someView_1);
aView_1.addFsToIndexes(x);
aView_2.addFsToIndexes(x);
// removes from view_1
aView_2.getAllIndexedFS(MyAnnotation.type).get().removeFromIndexes();
----------------------------------------------------
No, this currently removes from view 2. This is the same as the
example I gave, more or less. I think your proposal does not change
this behavior.
oops, that's right. I had forgotten that each view in the "before"
case has its own map from
CAS objects to JCas cover objects, so it would get a different cover
object.
My current leaning is toward the "most savings" choices, with updating
the preferred view on "new", get/next from iterators, and getView().
Let me restate this to see if I get it right. Basically the idea is
that when addToIndexes() or removeFromIndexes() are called on a
non-annotation object, it would affect the most recently used view.
(Where to "use" a view means any of: calling getView() for that view,
creating a new FS instance off of that view, or accessing the
iterators for that view.)
Consequence of this: the following have different behavior:
(1)
JCas someView_1 = baseJCas.getView(name1);
JCas someView_2 = baseJCas,getView(name2);
MyType annot_1 = new MyType(someView_1);
annot_1.addToIndexes(); //adds to someView_1
MyType annot_2 = new MyType(someView_2);
annot_2.addToIndexes(); //adds to someView_2
(2)
JCas someView_1 = baseJCas.getView(name1);
JCas someView_2 = baseJCas,getView(name2);
MyType annot_1 = new MyType(someView_1);
MyType annot_2 = new MyType(someView_2);
annot_1.addToIndexes(); //adds to someView_2 <<<<<< CHANGED
annot_2.addToIndexes(); //adds to someView_2
(In the current implementation, annot_1.addToIndexes() would add to
someView_1 in both cases.)
It seems strange to me that the call to annot_2 = new
MyType(someView_2) would affect what happens to annot_1. I admit that
this may just be a hypothetical example and that no annotators
actually do something like this. But it just doesn't seem like the
cleanest design. If we do decide to go with this I think I would want
to deprecate the methods at the same time.
I still prefer the semantics of my alternative suggestion to use
separate _Type objects (but shared generators and instance map), with
your idea of changing the _Type ref when an object is returned from an
iterator. Then the above code example works in what I think is a more
intuitive way.
So, the view ref for a JCas instance is "sticky" with that particular
JCas instance, and
changes when it's retrieved from another iterator.
I think the final decision comes down to: is the performance savings
we expect from eliminating the duplicate _Type objects worth the risk
that we might break an annotator.
I don't think there is a significant performance savings. So I'm
willing to go with the following
(let's see if I get this right...)
Changes:
1) 1 map from CAS objects to JCas cover objects, shared by all views
2) The getters from the iterators would *update* the _Type ref to be
the view associated with the iterator
* this might be implemented by changing the generators, using
reflection, or not - TBD
3) addto/removeFrom indexes for subtypes of Annotation_base use the
sofa ptr to get the right view.
These are not changed:
4) There is a set of _Type objects, one per view
Please let me know if I've overlooked something
-Marshall
Here's one more thing overlooked: There are 3 ways to generate JCas
cover objects: the 2 cited above (
"new" and "obtain from iterator", plus a third: dereference from
another object (follow a link from an FSRef value).
For this third case, with this impl, the value of the "view" would be
either the view it was created in, or the view it was
obtained from via an iterator, which ever happens last. So the same
code could return different behaviors depending on
execution order, some of which could be "remote" from the reference.
This is not ideal, to say the least. Some alternatives include
specifying the view when dereferencing (for instance, making it the
same view as the object it's being referred from (unless it's a
subtype of base-annotation).
Can people voice their opinions about this?
-Marshall
One other approach for this third thing would be to set the View to be
the base view. This would make addtoIndexes() and removeFromIndexes()
fail, for objects obtained this way. This is likely better, in my view,
than having them operate in a manner where other things could change
which view these were operating on.
When I try and imagine real use cases involving following dereferencing
of things in the CAS, followed by an addToIndex/RemoveFromIndex, I don't
come up with too much - and this would allow users to update their code
to do
these operations in a robust way. The only downside (besides breaking
running code for some small number of instances) is the case where users
were not using views at all. In this case, I'd like this to work as
before. And maybe that could be done, too.