You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@storm.apache.org by d2r <gi...@git.apache.org> on 2015/07/18 01:21:32 UTC

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

GitHub user d2r opened a pull request:

    https://github.com/apache/storm/pull/641

    [STORM-139] Correctly hash byte array tuple values

    * Unit test for correctness is included
    * The following tests showed no discernible difference in latency or throughput:
      * word_count, last 10min stats after being running > 10min
      * word_count modified to send byte[] words instead of Strings, same conditions
    
    This should handle the kinds of Objects we care about: reference types, all primitive array types, and reference array types.
    
    
    Using Java's .hashCode is a problem for distributed systems, as was pointed out in the JIRA.
    
    However, the behavior of [String#hashCode](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#hashCode%28%29), and the implementation of [java.util.Arrays#hashCode](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Arrays.java#Arrays.hashCode%28float[]%29) for all primitive array types is defined and should be consistent across JVMs.  This leaves Objects and Object[] that are not Strings.  In these cases, this change still trusts the hashCode method provided in those classes.
    
    In practice, bad cases should be rare.  In the cases when hashing is inconsistent and some sort of partitioning is used, it could be very difficult to debug.
    


You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/d2r/storm storm-138-byte-array-hashcode

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/storm/pull/641.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #641
    
----
commit 46b8c9e71b4b9b3f0e8c762fe070793e3f6d4971
Author: Derek Dagit <de...@yahoo-inc.com>
Date:   2015-07-17T21:54:32Z

    Correctly hash byte array tuple values

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

Posted by HeartSaVioR <gi...@git.apache.org>.
Github user HeartSaVioR commented on a diff in the pull request:

    https://github.com/apache/storm/pull/641#discussion_r35121430
  
    --- Diff: storm-core/src/jvm/backtype/storm/grouping/PartialKeyGrouping.java ---
    @@ -65,7 +66,11 @@ public void prepare(WorkerTopologyContext context, GlobalStreamId stream, List<I
                     List<Object> selectedFields = outFields.select(fields, values);
                     ByteBuffer out = ByteBuffer.allocate(selectedFields.size() * 4);
                     for (Object o: selectedFields) {
    -                    out.putInt(o.hashCode());
    +                    if (o instanceof Object[]) {
    --- End diff --
    
    @d2r 
    I didn't think about primitive array type.
    Actually I mean that,
    - Does 'o' have an chance to be instance of List? 
    - If then, could we apply ```((List)o).toArray()``` to convert it Object[], and let if statement handle it?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

Posted by vesense <gi...@git.apache.org>.
Github user vesense commented on the pull request:

    https://github.com/apache/storm/pull/641#issuecomment-123242642
  
    +1


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

Posted by HeartSaVioR <gi...@git.apache.org>.
Github user HeartSaVioR commented on a diff in the pull request:

    https://github.com/apache/storm/pull/641#discussion_r35109156
  
    --- Diff: storm-core/src/jvm/backtype/storm/grouping/PartialKeyGrouping.java ---
    @@ -65,7 +66,11 @@ public void prepare(WorkerTopologyContext context, GlobalStreamId stream, List<I
                     List<Object> selectedFields = outFields.select(fields, values);
                     ByteBuffer out = ByteBuffer.allocate(selectedFields.size() * 4);
                     for (Object o: selectedFields) {
    -                    out.putInt(o.hashCode());
    +                    if (o instanceof Object[]) {
    --- End diff --
    
    @d2r 
    Could we add same thing (converting List to Object[] by toArray, and apply Arrays.deepHashCode()) from list-hash-code to this?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

Posted by HeartSaVioR <gi...@git.apache.org>.
Github user HeartSaVioR commented on the pull request:

    https://github.com/apache/storm/pull/641#issuecomment-123884557
  
    LGTM, +1.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

Posted by harshach <gi...@git.apache.org>.
Github user harshach commented on the pull request:

    https://github.com/apache/storm/pull/641#issuecomment-122480198
  
    +1


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

Posted by d2r <gi...@git.apache.org>.
Github user d2r closed the pull request at:

    https://github.com/apache/storm/pull/641


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

Posted by d2r <gi...@git.apache.org>.
Github user d2r commented on a diff in the pull request:

    https://github.com/apache/storm/pull/641#discussion_r35127032
  
    --- Diff: storm-core/src/jvm/backtype/storm/grouping/PartialKeyGrouping.java ---
    @@ -65,7 +66,11 @@ public void prepare(WorkerTopologyContext context, GlobalStreamId stream, List<I
                     List<Object> selectedFields = outFields.select(fields, values);
                     ByteBuffer out = ByteBuffer.allocate(selectedFields.size() * 4);
                     for (Object o: selectedFields) {
    -                    out.putInt(o.hashCode());
    +                    if (o instanceof Object[]) {
    --- End diff --
    
    I see. Yes, I could add this.  However, since we do not currently do this in backtype.storm.tuple it would be inconsistent.
    
    In b.s.tuple, I always get a List<Object>.  I convert it to an array there because the call to Arrays#deepHashCode is simple.  If a tuple is _itself_ a List, then Arrays#hashCode will call List#hashCode on it.



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

Posted by d2r <gi...@git.apache.org>.
Github user d2r commented on a diff in the pull request:

    https://github.com/apache/storm/pull/641#discussion_r35120287
  
    --- Diff: storm-core/src/jvm/backtype/storm/grouping/PartialKeyGrouping.java ---
    @@ -65,7 +66,11 @@ public void prepare(WorkerTopologyContext context, GlobalStreamId stream, List<I
                     List<Object> selectedFields = outFields.select(fields, values);
                     ByteBuffer out = ByteBuffer.allocate(selectedFields.size() * 4);
                     for (Object o: selectedFields) {
    -                    out.putInt(o.hashCode());
    +                    if (o instanceof Object[]) {
    --- End diff --
    
    Yes, we need to catch the primitive array types as well somehow.
    
    Here `o` may not be a List.  I think we need to check not only `instanceof Object[]` but all of the other primitive array types as well.  Probably something like this?
    
    ```Java
    for (Object o: selectedFields) {
        if (o instanceof Object[]) {
            out.putInt(Arrays.deepHashCode((Object[])o));
        } else if (o instanceof byte[]) {
            out.putInt(Arrays.hashCode((byte[]) o));
        } else if (o instanceof short[]) {
            out.putInt(Arrays.hashCode((short[]) o));
        } else if (o instanceof int[]) {
            out.putInt(Arrays.hashCode((int[]) o));
        } else if (o instanceof long[]) {
            out.putInt(Arrays.hashCode((long[]) o));
        } else if (o instanceof char[]) {
            out.putInt(Arrays.hashCode((char[]) o));
        } else if (o instanceof float[]) {
            out.putInt(Arrays.hashCode((float[]) o));
        } else if (o instanceof double[]) {
            out.putInt(Arrays.hashCode((double[]) o));
        } else if (o instanceof boolean[]) {
            out.putInt(Arrays.hashCode((boolean[]) o));
        } else if (o != null) {
            out.putInt(o.hashCode());
        } else {
          out.putInt(0);
        }
    ```
    
    This seems to be what [Arrays#deepHashCode](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Arrays.java#3709) does.
    
    What do you think?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

Posted by d2r <gi...@git.apache.org>.
Github user d2r commented on the pull request:

    https://github.com/apache/storm/pull/641#issuecomment-123815242
  
    Ok, addressed comments.
    
    @HeartSaVioR, I made your suggested change as well.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

Posted by d2r <gi...@git.apache.org>.
Github user d2r commented on a diff in the pull request:

    https://github.com/apache/storm/pull/641#discussion_r35130923
  
    --- Diff: storm-core/src/clj/backtype/storm/tuple.clj ---
    @@ -15,8 +15,11 @@
     ;; limitations under the License.
     
     (ns backtype.storm.tuple
    -  (:import [java.util List]))
    +  (:import [java.util Arrays List]))
     
     (defn list-hash-code
       [^List alist]
    -  (.hashCode alist))
    +  (if (nil? alist)
    +    1
    +    (let [^"[Ljava.lang.Object;" array (.toArray alist)] ;; Object[]
    +      (Arrays/deepHashCode array))))
    --- End diff --
    
    The type hint here seems to be unnecessary.  I'll remove it.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

Posted by asfgit <gi...@git.apache.org>.
Github user asfgit closed the pull request at:

    https://github.com/apache/storm/pull/641


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] storm pull request: [STORM-139] Correctly hash byte array tuple va...

Posted by d2r <gi...@git.apache.org>.
GitHub user d2r reopened a pull request:

    https://github.com/apache/storm/pull/641

    [STORM-139] Correctly hash byte array tuple values

    * Unit test for correctness is included
    * The following tests showed no discernible difference in latency or throughput:
      * word_count, last 10min stats after being running > 10min
      * word_count modified to send byte[] words instead of Strings, same conditions
    
    This should handle the kinds of Objects we care about: reference types, all primitive array types, and reference array types.
    
    
    Using Java's .hashCode is a problem for distributed systems, as was pointed out in the JIRA.
    
    However, the behavior of [String#hashCode](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#hashCode%28%29), and the implementation of [java.util.Arrays#hashCode](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Arrays.java#Arrays.hashCode%28float[]%29) for all primitive array types is defined and should be consistent across JVMs.  This leaves Objects and Object[] that are not Strings.  In these cases, this change still trusts the hashCode method provided in those classes.
    
    In practice, bad cases should be rare.  In the cases when hashing is inconsistent and some sort of partitioning is used, it could be very difficult to debug.
    


You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/d2r/storm storm-138-byte-array-hashcode

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/storm/pull/641.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #641
    
----
commit b132520adb00def6d03ef020b1cb5973eb3b3519
Author: Derek Dagit <de...@yahoo-inc.com>
Date:   2015-07-17T23:45:39Z

    Correctly hash byte array tuple values

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---