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

Reply via email to