Why is FunctionListMap using identity to check values and not equals?

View: New views
5 Messages — Rating Filter:   Alert me  

Why is FunctionListMap using identity to check values and not equals?

by philk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I have the following situation:
private final EventList<E> items = GlazedLists.threadSafeList(new BasicEventList<E>());
private final DisposableMap<Key, E> itemsLookup = GlazedLists.syncEventListToMap(this.items,
        new FunctionList.Function<E, Key>() {
                public Key evaluate(final E sourceValue) {
                        return getKey(sourceValue);
                }
        });

I get updates from an external database that say which object (by key) has changed or was removed.
The removal using the itemsLookup works. However the put() method uses an Identity compare to find the item to be replaced. This is of course not working, since I am loading a new Object (different identity but same key) from the database every time. The object with the same Key should be replaced by using the equals method. How could I achieve that?

So when an Update comes in I do an
itemsLookup.put(key, database.load(key)) which naturally throws an exception because the new Object is not found in the base list.

Thanks,
Phil

Parent Message unknown Re: Why is FunctionListMap using identity to check values and not equals?

by Holger Brands :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Phil,

maybe there is a misunderstanding on my side or on your side.
In my opinion, FunctionListMap.put(K key, V value) does the following:

After checking the key-value-agreement it looks into the delegate map
to find the key. If it's not there, it adds the new value to the underlying EventList.
If the key is found, the (old) value is retrieved from the delegate map.
Then it iterates over the underlying EventList to find the *old* value by identity
to replace it with the *new* value. This looks correct to me.
The (new) value that is passed into the put-method is *not* used to compare
anything here.
I think one reason why the old value is searched by identity is,
that it's quite possible to have two equal objects with different keys (according
to the key-maker function).

Hope this helps,
Holger

>
> I have the following situation:
> private final EventList<E> items = GlazedLists.threadSafeList(new
> BasicEventList<E>());
> private final DisposableMap<Key, E> itemsLookup =
> GlazedLists.syncEventListToMap(this.items,
> new FunctionList.Function<E, Key>() {
> public Key evaluate(final E sourceValue) {
> return getKey(sourceValue);
> }
> });
>
> I get updates from an external database that say which object (by key) has
> changed or was removed.
> The removal using the itemsLookup works. However the put() method uses an
> Identity compare to find the item to be replaced. This is of course not
> working, since I am loading a new Object (different identity but same key)
> from the database every time. The object with the same Key should be
> replaced by using the equals method. How could I achieve that?
>
> So when an Update comes in I do an
> itemsLookup.put(key, database.load(key)) which naturally throws an exception
> because the new Object is not found in the base list.
>
> Thanks,
> Phil
> --
> View this message in context: http://www.nabble.com/Why-is-FunctionListMap-using-identity-to-check-values-and-not-equals--tp24066192p24066192.html
> Sent from the GlazedLists - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@...
> For additional commands, e-mail: users-help@...
>
>


___________________________________________________________________
WEB.DE FreeDSL Komplettanschluss mit DSL 6.000 Flatrate und
Telefonanschluss für 17,95 Euro/mtl.! http://produkte.web.de/go/02/


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...


Re: Why is FunctionListMap using identity to check values and not equals?

by philk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

If I get an item out of a DB two times it has a different identity each time. However it is the same object, as defined by the key (Primary key if you want so).

What I would like to have GL do for me is help me reacting to CRUD changes in the DB.
I get JMS messages when an item is created, removed or updated in the database. I want to reflect this change in my EventList.
For Create: add the new item
for update: refresh the item in the eventlist (if not existing, add it)
for delete: remove the item from my eventlist.

However using identities it is not possible to do. The lookup of items must be using the Key.

Hope its clear now :)

Holger Brands wrote:
Phil,

maybe there is a misunderstanding on my side or on your side.
In my opinion, FunctionListMap.put(K key, V value) does the following:

After checking the key-value-agreement it looks into the delegate map
to find the key. If it's not there, it adds the new value to the underlying EventList.
If the key is found, the (old) value is retrieved from the delegate map.
Then it iterates over the underlying EventList to find the *old* value by identity
to replace it with the *new* value. This looks correct to me.
The (new) value that is passed into the put-method is *not* used to compare
anything here.
I think one reason why the old value is searched by identity is,
that it's quite possible to have two equal objects with different keys (according
to the key-maker function).

Hope this helps,
Holger

>
> I have the following situation:
> private final EventList<E> items = GlazedLists.threadSafeList(new
> BasicEventList<E>());
> private final DisposableMap<Key, E> itemsLookup =
> GlazedLists.syncEventListToMap(this.items,
> new FunctionList.Function<E, Key>() {
> public Key evaluate(final E sourceValue) {
> return getKey(sourceValue);
> }
> });
>
> I get updates from an external database that say which object (by key) has
> changed or was removed.
> The removal using the itemsLookup works. However the put() method uses an
> Identity compare to find the item to be replaced. This is of course not
> working, since I am loading a new Object (different identity but same key)
> from the database every time. The object with the same Key should be
> replaced by using the equals method. How could I achieve that?
>
> So when an Update comes in I do an
> itemsLookup.put(key, database.load(key)) which naturally throws an exception
> because the new Object is not found in the base list.
>
> Thanks,
> Phil
> --
> View this message in context: http://www.nabble.com/Why-is-FunctionListMap-using-identity-to-check-values-and-not-equals--tp24066192p24066192.html
> Sent from the GlazedLists - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glazedlists.dev.java.net
> For additional commands, e-mail: users-help@glazedlists.dev.java.net
>
>


___________________________________________________________________
WEB.DE FreeDSL Komplettanschluss mit DSL 6.000 Flatrate und
Telefonanschluss für 17,95 Euro/mtl.! http://produkte.web.de/go/02/


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glazedlists.dev.java.net
For additional commands, e-mail: users-help@glazedlists.dev.java.net

Parent Message unknown Re: Why is FunctionListMap using identity to check values and not equals?

by Holger Brands :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I understand your use case but not your reasoning:

"So when an Update comes in I do an
itemsLookup.put(key, database.load(key))
which naturally throws an exception
because the new Object is not found in the base list."

As I tried to explain, the put-method does not try to find
the *new* value in the base list, so this can't be the cause
of the exception.

For example, let your items list contain object with identity x and key a.
So, itemsLookup.get(a) would return object x.

Then, you receive an update for key a, so you do
itemsLookup.put(a, database.load(a)) where database.load(a) would return
an object with identity y and key a.
The put-method will lookup the object for key a in its internal delegate map
and should find (the old) object x. Object x is then found by identity
in the base items list and replaced by object y.
The put-method can throw an IllegalStateException if it doesn't find the
*old* object in the base list.

But to help further we would have to see more example code and the concrete
exception with stacktrace...

Holger

BTW, I'm refering to GL 1.8.


>
> If I get an item out of a DB two times it has a different identity each time.
> However it is the same object, as defined by the key (Primary key if you
> want so).
>
> What I would like to have GL do for me is help me reacting to CRUD changes
> in the DB.
> I get JMS messages when an item is created, removed or updated in the
> database. I want to reflect this change in my EventList.
> For Create: add the new item
> for update: refresh the item in the eventlist (if not existing, add it)
> for delete: remove the item from my eventlist.
>
> However using identities it is not possible to do. The lookup of items must
> be using the Key.
>
> Hope its clear now :)
>
>
> Holger Brands wrote:
> >
> > Phil,
> >
> > maybe there is a misunderstanding on my side or on your side.
> > In my opinion, FunctionListMap.put(K key, V value) does the following:
> >
> > After checking the key-value-agreement it looks into the delegate map
> > to find the key. If it's not there, it adds the new value to the
> > underlying EventList.
> > If the key is found, the (old) value is retrieved from the delegate map.
> > Then it iterates over the underlying EventList to find the *old* value by
> > identity
> > to replace it with the *new* value. This looks correct to me.
> > The (new) value that is passed into the put-method is *not* used to
> > compare
> > anything here.
> > I think one reason why the old value is searched by identity is,
> > that it's quite possible to have two equal objects with different keys
> > (according
> > to the key-maker function).
> >
> > Hope this helps,
> > Holger
> >
> >>
> >> I have the following situation:
> >> private final EventList<E> items = GlazedLists.threadSafeList(new
> >> BasicEventList<E>());
> >> private final DisposableMap<Key, E> itemsLookup =
> >> GlazedLists.syncEventListToMap(this.items,
> >> new FunctionList.Function<E, Key>() {
> >> public Key evaluate(final E sourceValue) {
> >> return getKey(sourceValue);
> >> }
> >> });
> >>
> >> I get updates from an external database that say which object (by key)
> >> has
> >> changed or was removed.
> >> The removal using the itemsLookup works. However the put() method uses an
> >> Identity compare to find the item to be replaced. This is of course not
> >> working, since I am loading a new Object (different identity but same
> >> key)
> >> from the database every time. The object with the same Key should be
> >> replaced by using the equals method. How could I achieve that?
> >>
> >> So when an Update comes in I do an
> >> itemsLookup.put(key, database.load(key)) which naturally throws an
> >> exception
> >> because the new Object is not found in the base list.
> >>
> >> Thanks,
> >> Phil
> >> --
> >> View this message in context:
> >> http://www.nabble.com/Why-is-FunctionListMap-using-identity-to-check-values-and-not-equals--tp24066192p24066192.html
> >> Sent from the GlazedLists - User mailing list archive at Nabble.com.
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscribe@...
> >> For additional commands, e-mail: users-help@...
> >>
> >>
> >
> >
> > ___________________________________________________________________
> > WEB.DE FreeDSL Komplettanschluss mit DSL 6.000 Flatrate und
> > Telefonanschluss für 17,95 Euro/mtl.! http://produkte.web.de/go/02/
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@...
> > For additional commands, e-mail: users-help@...
> >
> >
> >
>
> --
> View this message in context: http://www.nabble.com/Why-is-FunctionListMap-using-identity-to-check-values-and-not-equals--tp24066192p24154654.html
> Sent from the GlazedLists - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@...
> For additional commands, e-mail: users-help@...
>
>


______________________________________________________
GRATIS für alle WEB.DE-Nutzer: Die maxdome Movie-FLAT!
Jetzt freischalten unter http://movieflat.web.de


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...


Re: Why is FunctionListMap using identity to check values and not equals?

by James Lemieux :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Holger's analysis is correct to my eye. FunctionListMap.put() is fine to use identity comparison when searching for the value to update in the valueList. This is because FunctionListMap guarantees that the delegate Map and valueList continually refer to the exact same (identical) objects.

Anywho, what IS possible is that you're being tripped up by concurrent access. If you want to write throught he map, and concurrent changes to the backing EventList are possible, you'd still need to .lock() the pipeline behind the FunctionListMap before attempting your put()s or get()s. Otherwise you could get RuntimeExceptions...

Just a thought. If you can reproduce your problem with a test case, we'll look at it with you.

James

On Thu, Jun 25, 2009 at 9:57 AM, Holger Brands <hbrands@...> wrote:
I understand your use case but not your reasoning:

"So when an Update comes in I do an
itemsLookup.put(key, database.load(key))
which naturally throws an exception
because the new Object is not found in the base list."

As I tried to explain, the put-method does not try to find
the *new* value in the base list, so this can't be the cause
of the exception.

For example, let your items list contain object with identity x and key a.
So, itemsLookup.get(a) would return object x.

Then, you receive an update for key a, so you do
itemsLookup.put(a, database.load(a)) where database.load(a) would return
an object with identity y and key a.
The put-method will lookup the object for key a in its internal delegate map
and should find (the old) object x. Object x is then found by identity
in the base items list and replaced by object y.
The put-method can throw an IllegalStateException if it doesn't find the
*old* object in the base list.

But to help further we would have to see more example code and the concrete
exception with stacktrace...

Holger

BTW, I'm refering to GL 1.8.


>
> If I get an item out of a DB two times it has a different identity each time.
> However it is the same object, as defined by the key (Primary key if you
> want so).
>
> What I would like to have GL do for me is help me reacting to CRUD changes
> in the DB.
> I get JMS messages when an item is created, removed or updated in the
> database. I want to reflect this change in my EventList.
> For Create: add the new item
> for update: refresh the item in the eventlist (if not existing, add it)
> for delete: remove the item from my eventlist.
>
> However using identities it is not possible to do. The lookup of items must
> be using the Key.
>
> Hope its clear now :)
>
>
> Holger Brands wrote:
> >
> > Phil,
> >
> > maybe there is a misunderstanding on my side or on your side.
> > In my opinion, FunctionListMap.put(K key, V value) does the following:
> >
> > After checking the key-value-agreement it looks into the delegate map
> > to find the key. If it's not there, it adds the new value to the
> > underlying EventList.
> > If the key is found, the (old) value is retrieved from the delegate map.
> > Then it iterates over the underlying EventList to find the *old* value by
> > identity
> > to replace it with the *new* value. This looks correct to me.
> > The (new) value that is passed into the put-method is *not* used to
> > compare
> > anything here.
> > I think one reason why the old value is searched by identity is,
> > that it's quite possible to have two equal objects with different keys
> > (according
> > to the key-maker function).
> >
> > Hope this helps,
> > Holger
> >
> >>
> >> I have the following situation:
> >> private final EventList<E> items = GlazedLists.threadSafeList(new
> >> BasicEventList<E>());
> >> private final DisposableMap<Key, E> itemsLookup =
> >> GlazedLists.syncEventListToMap(this.items,
> >>    new FunctionList.Function<E, Key>() {
> >>            public Key evaluate(final E sourceValue) {
> >>                    return getKey(sourceValue);
> >>            }
> >>    });
> >>
> >> I get updates from an external database that say which object (by key)
> >> has
> >> changed or was removed.
> >> The removal using the itemsLookup works. However the put() method uses an
> >> Identity compare to find the item to be replaced. This is of course not
> >> working, since I am loading a new Object (different identity but same
> >> key)
> >> from the database every time. The object with the same Key should be
> >> replaced by using the equals method. How could I achieve that?
> >>
> >> So when an Update comes in I do an
> >> itemsLookup.put(key, database.load(key)) which naturally throws an
> >> exception
> >> because the new Object is not found in the base list.
> >>
> >> Thanks,
> >> Phil
> >> --
> >> View this message in context:
> >> http://www.nabble.com/Why-is-FunctionListMap-using-identity-to-check-values-and-not-equals--tp24066192p24066192.html
> >> Sent from the GlazedLists - User mailing list archive at Nabble.com.
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscribe@...
> >> For additional commands, e-mail: users-help@...
> >>
> >>
> >
> >
> > ___________________________________________________________________
> > WEB.DE FreeDSL Komplettanschluss mit DSL 6.000 Flatrate und
> > Telefonanschluss für 17,95 Euro/mtl.! http://produkte.web.de/go/02/
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@...
> > For additional commands, e-mail: users-help@...
> >
> >
> >
>
> --
> View this message in context: http://www.nabble.com/Why-is-FunctionListMap-using-identity-to-check-values-and-not-equals--tp24066192p24154654.html
> Sent from the GlazedLists - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@...
> For additional commands, e-mail: users-help@...
>
>


______________________________________________________
GRATIS für alle WEB.DE-Nutzer: Die maxdome Movie-FLAT!
Jetzt freischalten unter http://movieflat.web.de


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...