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.goncha...@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 <akuznet...@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

Reply via email to