-
Notifications
You must be signed in to change notification settings - Fork 155
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
Kryo 3.0.3 upgrade #245
Kryo 3.0.3 upgrade #245
Changes from 12 commits
dcef00f
2a064a4
bb52eee
7596f6c
a0909b7
f6d462e
defab77
3ef80a6
cd993e3
843fc0c
8e8ab86
b51eee4
76905cc
5bf625c
29ad0db
d0dd574
e0b809e
a885f3d
b234e46
1ec4dc3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
/** | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
/** | ||
* Taken from org.apache.mahout.math | ||
* https://github.com/apache/mahout | ||
*/ | ||
|
||
package com.twitter.chill.hadoop; | ||
|
||
import java.io.DataInputStream; | ||
import java.io.DataOutputStream; | ||
import java.io.IOException; | ||
|
||
/** | ||
* <p>Encodes signed and unsigned values using a common variable-length | ||
* scheme, found for example in | ||
* <a href="http://code.google.com/apis/protocolbuffers/docs/encoding.html"> | ||
* Google's Protocol Buffers</a>. It uses fewer bytes to encode smaller values, | ||
* but will use slightly more bytes to encode large values.</p> | ||
* | ||
* <p>Signed values are further encoded using so-called zig-zag encoding | ||
* in order to make them "compatible" with variable-length encoding.</p> | ||
*/ | ||
final class Varint { | ||
|
||
private Varint() { | ||
} | ||
|
||
/** | ||
* Encodes a value using the variable-length encoding from | ||
* <a href="http://code.google.com/apis/protocolbuffers/docs/encoding.html"> | ||
* Google Protocol Buffers</a>. It uses zig-zag encoding to efficiently | ||
* encode signed values. If values are known to be nonnegative, | ||
* {@link #writeUnsignedVarLong(long, java.io.DataOutputStream)} should be used. | ||
* | ||
* @param value value to encode | ||
* @param out to write bytes to | ||
* @throws java.io.IOException if {@link java.io.DataOutput} throws {@link java.io.IOException} | ||
*/ | ||
public static void writeSignedVarLong(long value, DataOutputStream out) throws IOException { | ||
// Great trick from http://code.google.com/apis/protocolbuffers/docs/encoding.html#types | ||
writeUnsignedVarLong((value << 1) ^ (value >> 63), out); | ||
} | ||
|
||
/** | ||
* Encodes a value using the variable-length encoding from | ||
* <a href="http://code.google.com/apis/protocolbuffers/docs/encoding.html"> | ||
* Google Protocol Buffers</a>. Zig-zag is not used, so input must not be negative. | ||
* If values can be negative, use {@link #writeSignedVarLong(long, java.io.DataOutputStream)} | ||
* instead. This method treats negative input as like a large unsigned value. | ||
* | ||
* @param value value to encode | ||
* @param out to write bytes to | ||
* @throws java.io.IOException if {@link java.io.DataOutputStream} throws {@link java.io.IOException} | ||
*/ | ||
public static void writeUnsignedVarLong(long value, DataOutputStream out) throws IOException { | ||
while ((value & 0xFFFFFFFFFFFFFF80L) != 0L) { | ||
out.writeByte(((int) value & 0x7F) | 0x80); | ||
value >>>= 7; | ||
} | ||
out.writeByte((int) value & 0x7F); | ||
} | ||
|
||
/** | ||
* @see #writeSignedVarLong(long, java.io.DataOutputStream) | ||
*/ | ||
public static void writeSignedVarInt(int value, DataOutputStream out) throws IOException { | ||
// Great trick from http://code.google.com/apis/protocolbuffers/docs/encoding.html#types | ||
writeUnsignedVarInt((value << 1) ^ (value >> 31), out); | ||
} | ||
|
||
/** | ||
* @see #writeUnsignedVarLong(long, java.io.DataOutputStream) | ||
*/ | ||
public static void writeUnsignedVarInt(int value, DataOutputStream out) throws IOException { | ||
while ((value & 0xFFFFFF80) != 0L) { | ||
out.writeByte((value & 0x7F) | 0x80); | ||
value >>>= 7; | ||
} | ||
out.writeByte(value & 0x7F); | ||
} | ||
|
||
/** | ||
* @param in to read bytes from | ||
* @return decode value | ||
* @throws java.io.IOException if {@link java.io.DataInput} throws {@link java.io.IOException} | ||
* @throws IllegalArgumentException if variable-length value does not terminate | ||
* after 9 bytes have been read | ||
* @see #writeSignedVarLong(long, java.io.DataOutputStream) | ||
*/ | ||
public static long readSignedVarLong(DataInputStream in) throws IOException { | ||
long raw = readUnsignedVarLong(in); | ||
// This undoes the trick in writeSignedVarLong() | ||
long temp = (((raw << 63) >> 63) ^ raw) >> 1; | ||
// This extra step lets us deal with the largest signed values by treating | ||
// negative results from read unsigned methods as like unsigned values | ||
// Must re-flip the top bit if the original read value had it set. | ||
return temp ^ (raw & (1L << 63)); | ||
} | ||
|
||
/** | ||
* @param in to read bytes from | ||
* @return decode value | ||
* @throws java.io.IOException if {@link java.io.DataInput} throws {@link java.io.IOException} | ||
* @throws IllegalArgumentException if variable-length value does not terminate | ||
* after 9 bytes have been read | ||
* @see #writeUnsignedVarLong(long, java.io.DataOutputStream) | ||
*/ | ||
public static long readUnsignedVarLong(DataInputStream in) throws IOException { | ||
long value = 0L; | ||
int i = 0; | ||
long b; | ||
while (((b = in.readByte()) & 0x80L) != 0) { | ||
value |= (b & 0x7F) << i; | ||
i += 7; | ||
} | ||
return value | (b << i); | ||
} | ||
|
||
/** | ||
* @throws IllegalArgumentException if variable-length value does not terminate | ||
* after 5 bytes have been read | ||
* @throws java.io.IOException if {@link java.io.DataInput} throws {@link java.io.IOException} | ||
* @see #readSignedVarLong(java.io.DataInputStream) | ||
*/ | ||
public static int readSignedVarInt(DataInputStream in) throws IOException { | ||
int raw = readUnsignedVarInt(in); | ||
// This undoes the trick in writeSignedVarInt() | ||
int temp = (((raw << 31) >> 31) ^ raw) >> 1; | ||
// This extra step lets us deal with the largest signed values by treating | ||
// negative results from read unsigned methods as like unsigned values. | ||
// Must re-flip the top bit if the original read value had it set. | ||
return temp ^ (raw & (1 << 31)); | ||
} | ||
|
||
/** | ||
* @throws IllegalArgumentException if variable-length value does not terminate | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is a lie, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like one(this code isn't mine), add test, or kill comment?
Looks like it would fix this one |
||
* after 5 bytes have been read | ||
* @throws java.io.IOException if {@link java.io.DataInput} throws {@link java.io.IOException} | ||
* @see #readUnsignedVarLong(java.io.DataInputStream) | ||
*/ | ||
public static int readUnsignedVarInt(DataInputStream in) throws IOException { | ||
int value = 0; | ||
int i = 0; | ||
int b; | ||
while (((b = in.readByte()) & 0x80) != 0) { | ||
value |= (b & 0x7F) << i; | ||
i += 7; | ||
} | ||
return value | (b << i); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,8 +102,8 @@ class KryoBase extends Kryo { | |
object Instantiators { | ||
// Go through the list and use the first that works | ||
def newOrElse(cls: Class[_], | ||
it: TraversableOnce[Class[_] => Either[Throwable, ObjectInstantiator]], | ||
elsefn: => ObjectInstantiator): ObjectInstantiator = { | ||
it: TraversableOnce[Class[_] => Either[Throwable, ObjectInstantiator[AnyRef]]], | ||
elsefn: => ObjectInstantiator[_]): ObjectInstantiator[_] = { | ||
// Just go through and try each one, | ||
it.map { fn => | ||
fn(cls) match { | ||
|
@@ -117,8 +117,8 @@ object Instantiators { | |
} | ||
|
||
// Use call by name: | ||
def forClass(t: Class[_])(fn: () => Any): ObjectInstantiator = | ||
new ObjectInstantiator { | ||
def forClass(t: Class[_])(fn: () => Any): ObjectInstantiator[AnyRef] = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't this be: def forClass[T](t: Class[T])(fn: () => T): ObjectInstantiator[T] =
new ObjectInstantiator[T] {
override def newInstance() = {
try { fn() } |
||
new ObjectInstantiator[AnyRef] { | ||
override def newInstance() = { | ||
try { fn().asInstanceOf[AnyRef] } | ||
catch { | ||
|
@@ -130,7 +130,7 @@ object Instantiators { | |
} | ||
|
||
// This one tries reflectasm, which is a fast way of constructing an object | ||
def reflectAsm(t: Class[_]): Either[Throwable, ObjectInstantiator] = { | ||
def reflectAsm(t: Class[_]): Either[Throwable, ObjectInstantiator[AnyRef]] = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also can we add the |
||
try { | ||
val access = ConstructorAccess.get(t) | ||
// Try it once, because this isn't always successful: | ||
|
@@ -154,7 +154,7 @@ object Instantiators { | |
} | ||
} | ||
|
||
def normalJava(t: Class[_]): Either[Throwable, ObjectInstantiator] = { | ||
def normalJava(t: Class[_]): Either[Throwable, ObjectInstantiator[AnyRef]] = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add |
||
try { | ||
val cons = getConstructor(t) | ||
Right(forClass(t) { () => cons.newInstance() }) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there no int? should we throw here if the long > Int.MaxValue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, the code is below. Why not unsigned varint?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this flowed out of the kryo api for bytes written returning a long... at the entry point to that i goto an int now, so everything else just ends up being integers