Noted while working on RUBY-332.
The Java driver currently encodes CQL duration types by promoting the year and month ints to longs followed by a 64-bit zigzag encoding for these values + the long nanos value. Initially it seemed strange to use a 64-bit zigzag encoding function on a 32-bit value; it seemed like you'd be pulling the sign bit from the wrong place. The function is correct, however, since pad bits on a right shift are derived from the MSB in the incoming value. So 63 right shifts on a 32-bit val still leaves you with the same val you'd get from 31 right shifts... you just did more work than you needed to.
This ticket should include the following changes:
Addressing the extra work described above. Provide an explicit 32-bit zigzag encoding and use it when possible.
Follow-on from the point above: avoid the int->long promotion for years and months that's currently happening for duration types. This is likely necessary in order to leverage a 32-bit zigzag function
These optimizations only affect encoding so they would only come into play when you're sending large amounts of vint encoded data from the driver. And even in those cases the suspicion is any actual performance hit would be quite small.
Also noted by in conversation around this issue: the Java driver appears to be calling computeUnsignedVIntSize() twice for the same data during the encoding process. We should probably try to reduce this down to a single call as well. Again, this likely won't have much of an impact on performance... but there's no point in doing unnecessary work if we can avoid it.