ignite-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alexey Goncharuk <alexey.goncha...@gmail.com>
Subject Re: Portables hash code.
Date Thu, 29 Oct 2015 14:19:23 GMT
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
>

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