Hi,

On 2015-02-15, 12:19 AM, "OC" wrote:

Chuck,

On 15. 2. 2015, at 1:56, Chuck Hill 
<[email protected]<mailto:[email protected]>> wrote:

=== my EO code ===
    public NSArray orderedPriceOffers {
        NSArray offers=priceOffers() // this is a modelled relationship
        if (offers==null || offers.count<2) return offers
        try {
            offers=offers.sortedArrayUsingComparator(new OCSDateComparator())
        } catch (Exception exc) {
            ... never happens anyway, no need to show ...
        }
        return offers
    }
    public DBPriceOffer lastValidPriceOffer {
        NSArray a=orderedPriceOffers()
        if (a==null || a.count==0) return null
        for (int n=a.count-1;n>=0;n--) {
            DBPriceOffer po=(DBPriceOffer)a.objectAtIndex(n)
            if (po.validOffer()) // this is a modelled boolean attribute
               return po
        }
        return null
    }
...
@OCStandard class OCSDateComparator extends NSComparator {
    public int compare(Object left,Object right) {
        DBPriceOffer l=(DBPriceOffer)left,r=(DBPriceOffer)right
        return l.creationDate().compare(r.creationDate()) // modelled timestamp 
attribute, always set creation-time
    }
}
===
It would be very beneficial to speed up orderedPriceOffers,
To speed up lastValidPriceOffer or for some other reason?

It is used elsewhere too, and although it is not that pressing as 
lastValidPriceOffer (which is used at more places), it would help to speed it 
up, too.

I am assuming this is a large list.

Alas, it is. When written and tested years ago, there used be tens of items 
max; today they use the code with thousands of items, and that's a big problem 
which I have to solve ASAP :)

You could sort and cache on the EO and invalidate the cache if the relationship 
changes.  Sorting at the database is usually faster, especially if there is a 
usable index.

This is precisely what I don't know howto, can you help? I found no way to 
force the SELECT caused by firing a relationship fault to use any ORDER BY.

You can’t. Stop thinking about it.  :-)  Unless you are prepared to perform 
major surgery on EOF.



Or do you suggest that I don't use a modelled relationship at all, implementing 
something like

=== [*]
private cache
def orderedPriceOffers {
if (cache) return cache
cache=this.editingContext.objectsWithFetchSpecification( yadda yadda incl sort 
orderings )
}
def addPriceOffer {
cache=nil
...
}
===

Yes, that is more what I had in mind.  Or fetch the sorted list as needed.

If you only need the single, most recent valid price, then fetch that.  Why 
fetch in what you will never need?  Do you often need the details of those 
thousand of items in the relationship?  Just because you can model it, does not 
mean that you have to model it.



I thought caching objects this way was an extremely big no-no? Besides even at 
the first look I can see lots of possible catches and gotchas, with different 
ECs, with objects inserted but not-yet-saved, etc...

I was thinking more of fetch exactly what you need on demand than of caching.  
You can cache, but at you note it gets very complicated quickly.



and it is a must to speed up lastValidPriceOffer -- very considerably, 
preferrably to O(1) if possible.
I’d model a to-one and update this when the priceOffers relationship changes.

Hmmm... actually, does this differ anyhow from caching the GID? (Save for the 
first access, for cached GID is not stored in the DB, and thus forces search 
once.)

A to-one is simply cached PK, stored in DB, or am I overlooking something?

EOF handles a lot of the complexities for you.



Note that the price offers are always sorted by their creation date -- never 
otherwise --, which effectively means new objects are always added to the end 
of the sorted array, never ever inserted. Also, price offers are not editable; 
once stored, they never change, both validOffer and creationDate attributes 
stay unchanged forever (other ones too, which is irrelevant here).
It seems to me, given this business logic, it would be best
- to fetch the fault using a sort ordering, to ensure it fetches appropriately 
ordered
- whenever a new object is added to an already fetched relationship, to add it 
to the end of the array the EO stack maintains.
Except that, as you note below, relationships in EOF are unordered sets.  EOF 
makes no guarantees about maintain an ordering in the relationship.

Well there must be _some_ reason they used NSArrays instead of NSSets I guess.

Either it was a design error, or they intended to make them ordered.  In either 
case, there is no support for ordered relationships.



Don’t fight EOF.  Un-ordered set are un-ordered sets.

Anyway, I don't really want to fight EOF; rather I would co-operate with it to 
get the best result.

In this case the best result would be
(a) to fetch sorted with ORDER BY into an array
(b) to add newly created objects to the end of the array

“Not gonna happen”  :-)



Seems to me somewhat too far at the ubiquitous side for EOF/Wonder not to 
support anything remotely similar and leaving me completely on me own with 
something like [*]? But perhaps it's just the way the things are :)

It gets complicated quickly.  It is not an easy thing to bolt onto EOF.  I 
think that most people just found a different way to achieve their goals.


As for lastValidPriceOffer, I tried to cache the object's permanentGlobalID 
when found or added new valid one (caching the object itself failed with 
different ECs), but it still does not work well, and is terribly ugly and 
error-prone.
Why not just model it?  It is a real thing.

Well I sort of never thought of that :)

:-)

Chuck


That aside, for this app it is somewhat inconvenient to change the DB schema. 
For the next release I will do that.

Thanks a lot,
OC


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      
([email protected]<mailto:[email protected]>)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/chill%40gevityinc.com

This email sent to [email protected]<mailto:[email protected]>
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to