Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract ID generation methods to new public IdUtils class #724

Merged
merged 1 commit into from
Apr 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 6 additions & 41 deletions epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
import androidx.annotation.Nullable;
import androidx.annotation.Px;

import static com.airbnb.epoxy.IdUtils.hashLong64Bit;
import static com.airbnb.epoxy.IdUtils.hashString64Bit;

/**
* Helper to bind data to a view using a builder style. The parameterized type should extend
* Android's View.
Expand Down Expand Up @@ -237,7 +240,7 @@ public EpoxyModel<T> id(long id1, long id2) {
* several hundred models in the adapter, there would be roughly 1 in 100 trillion chance of a
* collision. (http://preshing.com/20110504/hash-collision-probabilities/)
*
* @see EpoxyModel#hashString64Bit(CharSequence)
* @see IdUtils#hashString64Bit(CharSequence)
*/
public EpoxyModel<T> id(@Nullable CharSequence key) {
id(hashString64Bit(key));
Expand Down Expand Up @@ -268,8 +271,8 @@ public EpoxyModel<T> id(@Nullable CharSequence key, @Nullable CharSequence... ot
* several hundred models in the adapter, there would be roughly 1 in 100 trillion chance of a
* collision. (http://preshing.com/20110504/hash-collision-probabilities/)
*
* @see EpoxyModel#hashString64Bit(CharSequence)
* @see EpoxyModel#hashLong64Bit(long)
* @see IdUtils#hashString64Bit(CharSequence)
* @see IdUtils#hashLong64Bit(long)
*/
public EpoxyModel<T> id(@Nullable CharSequence key, long id) {
long result = hashString64Bit(key);
Expand All @@ -278,44 +281,6 @@ public EpoxyModel<T> id(@Nullable CharSequence key, long id) {
return this;
}

/**
* Hash a long into 64 bits instead of the normal 32. This uses a xor shift implementation to
* attempt psuedo randomness so object ids have an even spread for less chance of collisions.
* <p>
* From http://stackoverflow.com/a/11554034
* <p>
* http://www.javamex.com/tutorials/random_numbers/xorshift.shtml
*/
private static long hashLong64Bit(long value) {
value ^= (value << 21);
value ^= (value >>> 35);
value ^= (value << 4);
return value;
}

/**
* Hash a string into 64 bits instead of the normal 32. This allows us to better use strings as a
* model id with less chance of collisions. This uses the FNV-1a algorithm for a good mix of speed
* and distribution.
* <p>
* Performance comparisons found at http://stackoverflow.com/a/1660613
* <p>
* Hash implementation from http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-1a
*/
private static long hashString64Bit(@Nullable CharSequence str) {
if (str == null) {
return 0;
}

long result = 0xcbf29ce484222325L;
final int len = str.length();
for (int i = 0; i < len; i++) {
result ^= str.charAt(i);
result *= 0x100000001b3L;
}
return result;
}

/**
* Return the default layout resource to be used when creating views for this model. The resource
* will be inflated to create a view for the model; additionally the layout int is used as the
Expand Down
49 changes: 49 additions & 0 deletions epoxy-adapter/src/main/java/com/airbnb/epoxy/IdUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.airbnb.epoxy;

import androidx.annotation.Nullable;

/**
* Utilities for generating 64-bit long IDs from types such as {@link CharSequence}.
*/
public final class IdUtils {
private IdUtils() {
}

/**
* Hash a long into 64 bits instead of the normal 32. This uses a xor shift implementation to
* attempt psuedo randomness so object ids have an even spread for less chance of collisions.
* <p>
* From http://stackoverflow.com/a/11554034
* <p>
* http://www.javamex.com/tutorials/random_numbers/xorshift.shtml
*/
public static long hashLong64Bit(long value) {
value ^= (value << 21);
value ^= (value >>> 35);
value ^= (value << 4);
return value;
}

/**
* Hash a string into 64 bits instead of the normal 32. This allows us to better use strings as a
* model id with less chance of collisions. This uses the FNV-1a algorithm for a good mix of speed
* and distribution.
* <p>
* Performance comparisons found at http://stackoverflow.com/a/1660613
* <p>
* Hash implementation from http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-1a
*/
public static long hashString64Bit(@Nullable CharSequence str) {
if (str == null) {
return 0;
}

long result = 0xcbf29ce484222325L;
final int len = str.length();
for (int i = 0; i < len; i++) {
result ^= str.charAt(i);
result *= 0x100000001b3L;
}
return result;
}
}