ignite-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alexey Kuznetsov <akuznet...@gridgain.com>
Subject Re: Portables hash code.
Date Fri, 30 Oct 2015 08:02:39 GMT
Thanks, Dmitriy.

I think your solution is more straightforward, no need to create wrappers.

Will implement this way.

On Fri, Oct 30, 2015 at 6:00 AM, Dmitriy Setrakyan <dsetrakyan@apache.org>
wrote:

> I am not sure I like this. We now require creation of some sort of
> BuilderIgniteObjectView, which looks a bit over the top for me.
>
> How about using the hasher to calculate the hash-code and setting it into
> the builder manually in your implementation? To my knowledge, builder
> allows you to get individual field values, so you can get all the values
> required to calculate the hash value:
>
> For example, here is what a hasher can look like:
>
> —————-
> interface JdbcTypeHasher {
>     int hashCode(Collection<?> values);
> }
> —————-
>
> Then, somewhere in your code, you will set the hash-code on the builder
> yourself:
>
> —————
> IgniteObjectBuilder builder = …; // initialize
>
> Collection<?> c = new ArrayList<>();
>
> for (each field required for hash) {
>     c.add(builder.getField(name));
> }
>
> int hash = hasher.hashCode(c);
>
> builder.hashCode(hash); // Set hash-code on the builder.
> ——————
>
> Thoughts?
>
> D.
>
> On Thu, Oct 29, 2015 at 7:23 AM, Alexey Kuznetsov <akuznetsov@gridgain.com
> >
> wrote:
>
> > Alexey,
> >
> > I like this very much, this almost solve my problems and I do not need
> any
> > fabrics!
> >
> > Thanks!
> >
> > On Thu, Oct 29, 2015 at 9:19 PM, Alexey Goncharuk <
> > alexey.goncharuk@gmail.com> wrote:
> >
> > > Alexey,
> > >
> > > What if we create a thin wrapper around PortableBuilder that implements
> > > IgniteObject? Since PortableBuilder already has getField() method, you
> > only
> > > need to delegate to a builder in this wrapper. Then we can invoke the
> > > interface Dmitriy suggested, obtain hashCode and set it back to the
> > > builder.
> > >
> > > In pseudo-code:
> > >
> > > PortableBuilder bld = getBuilder();
> > >
> > > populateFromResultSet(bld);
> > >
> > > IgniteObject bldView = new BuilderIgniteObjectView(bld);
> > >
> > > int hashCode = hashBuilder.hashCode(bldView);
> > > bld.hashCode(hashCode);
> > >
> > > bld.build();
> > >
> > >
> > > Thoughts?
> > >
> > > 2015-10-29 16:34 GMT+03:00 Alexey Kuznetsov <akuznetsov@gridgain.com>:
> > >
> > > > Dmitriy,
> > > >
> > > > > How about adding JdbcTypeHasher interface, which will look like
> this:
> > > > > interface JdbcTypeHasher {
> > > > >    public int hashCode(IgniteObject o, Collection<String> fields);
> > > > >}
> > > > > User should be optionally set this interface at the JdbcType level.
> > If
> > > > not
> > > > > set, then we use our default implementation.
> > > > > Will this work?
> > > >
> > > > First I thought it will work, but when I started to implement hasher
> > > > support I faced several problems:
> > > >   1) IgniteObject/PortableObject is actually immutable, so setting
> > > hashcode
> > > > for already constructed object looks dirty (set several bytes in
> array
> > at
> > > > certain offset).
> > > >   2) It is not very efficient from implementation point of jdbc pojo
> > > store
> > > > (on more cycle over object fields with not very efficient access by
> > name)
> > > >
> > > > So, I came to this solution:
> > > >
> > > > // Hash builder.
> > > > public interface JdbcTypeHashBuilder {
> > > >     // Calculate hash code for specified value and field name.
> > > >     public int toHash(Object val, String typeName, String fieldName);
> > > >
> > > >     // Calculated hash code.
> > > >     public int hash();
> > > > }
> > > >
> > > > // Default implementation of JdbcTypeHashBuilder. User could
> implement
> > > its
> > > > own if needed.
> > > > public class JdbcTypeDefaultHashBuilder implements
> JdbcTypeHashBuilder
> > {
> > > >     private int hash = 0;
> > > >
> > > >     @Override public int toHash(Object val, String typeName, String
> > > > fieldName) {
> > > >         hash = 31 * hash + (val != null ? val.hashCode() : 0);
> > > >
> > > >         return hash;
> > > >     }
> > > >
> > > >     @Override public int hash() {
> > > >         return hash;
> > > >     }
> > > > }
> > > >
> > > > // Factory for creating default hash builder:
> > > > public class JdbcTypeDefaultHashBuilderFactory implements
> > > > Factory<JdbcTypeHashBuilder> {
> > > >     private static final long serialVersionUID = 0L;
> > > >
> > > >     /** Instance of factory for reuse. */
> > > >     public final static JdbcTypeDefaultHashBuilderFactory INSTANCE =
> > new
> > > > JdbcTypeDefaultHashBuilderFactory();
> > > >
> > > >     @Override public JdbcTypeHashBuilder create() {
> > > >         return new JdbcTypeDefaultHashBuilder();
> > > >     }
> > > > }
> > > >
> > > > And I add factory to CacheJdbcPojoStoreConfiguration {
> > > > ....
> > > >   private Factory<JdbcTypeHashBuilder> hashBuilderFactory =
> > > > JdbcTypeDefaultHashBuilderFactory.INSTANCE;
> > > > }
> > > >
> > > > Now I could build PortableObject and calculate its hash at the same
> > time:
> > > > ...
> > > > portableBuilder = ...
> > > >
> > > > hashBuilder = factory.create();
> > > >
> > > > for (dbField: dbFields) {
> > > >   Object val = dbField.getValue();
> > > >
> > > >  portableBuilder.setField(dbField.getJavaName(), val) ;
> > > >  hashBuilder.toHash(val, typeName, dbField.getJavaName());
> > > > }
> > > >
> > > > return portableBuilder.hashCode(hashBuilder.hash()).build();
> > > >
> > > > Thoughts?
> > > >
> > > > --
> > > > Alexey Kuznetsov
> > > > GridGain Systems
> > > > www.gridgain.com
> > > >
> > >
> >
> >
> >
> > --
> > Alexey Kuznetsov
> > GridGain Systems
> > www.gridgain.com
> >
>



-- 
Alexey Kuznetsov
GridGain Systems
www.gridgain.com

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message