Skip to content

rkalla/common-lib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

73 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The Buzz Media common-lib
http://www.thebuzzmedia.com/software/common-lib-common-java-utility-library/


Changelog
---------
2.3
	* Added StreamUtils to make processing streams for their content easier.
	
	* Added FailedTaskException to be able to reported the reason of a failed
	task in more depth to the caller. Now AbstractRetryableTask is specified to
	throw RuntimeExceptions in the case of fundamental errors (like thread 
	interruption) but to throw this new type any time a task fails to complete.
	
	* Modified AbstractRetryableTask behavior when a sleeping thread is interrupted
	by having it gracefully exit instead of throwing a RuntimeException.
	
	A task being interrupted is an expected event if the task is being executed by
	an ExecutorService that just had shutdownNow() called on it; throwing an
	exception in response to this event was inappropriate.
	 
	* In addition to the interruption behavior, AbstractRetryableTask was
	enhanced by adding an "isInterrupted()" state so the caller can tell if their
	task completed normally OR if the executing thread was interrupted and that
	is why the call() method returned. 
	
	If the caller cares, they can choose to retry the task (overcoming the interruption)
	or if they expected the interruption (shutting down an ExecutorService) then 
	they can gracefully continue exiting.
	
	* Modified AbstractRetryableTask to retry a default of 5 times instead of 3.
	
	* Added "retryAttempt" value to callImpl making it easier for call implementation
	to tell if they have run before and which attempt they are on.
	
	* Corrected the retry count logic in AbsractRetryableTask.
	
	* Added OAuthSigner class which provides core OAuth-spec-compliant functionality
	like helping with the signature/HMAC generation.
	
	* OAuthSigner.Algorithm defines support for MD5, SHA-1, SHA-256 and SHA-512
	hashing when generating signatures.
	
	* Added the "escape" sub-package with direct copies of the 4 escaping class
	implementations from Google's API Client Library. 
	
	This was necessary for the OAuthSigner to generate correct signatures, using
	the embedded URLEncoder from the JDK does not perform the encoding that the
	OAuth spec requires (slightly modified version of RFC-3629).
	
	The 4 classes were pulled in instead of adding the 240kb JAR as a dependency
	for this library.
	
	* Added iHarder's Base64 implementation (required by OAuthSigner)
	http://iharder.sourceforge.net/current/java/base64/
	
	This is a superior Base64 Java implementation utilized by the OAuthSigner class
	and I wanted to avoid shipping a new JAR dependency. Since iHarder is only a
	single, well-designed class with a wide-open license, I felt it was easier 
	(and more convenient) to simply add it to the library as-is to the benefit 
	of anyone else needing a Base64 implementation.
	
	The class is clearly documented as being directly transplanted from the 
	iHarder Base64 project; all credit should be directed to Robert Harder
	([email protected]) for this class.
	
	* Changed "tbm.common.util.decode.maxBufferSize" and "tbm.common.util.encode.maxBufferSize"
	property names by dropping the ".util" middle portion.

2.2
	* Added IInput input definition.
	
	IInput represents a powerful way to wrap any kind of readable input with a
	common, generics-enhanced interface and read from it given a target buffer.
	
	IInputs are a unifying structure at a higher level than similar approaches
	like InputStream, Reader or even NIO's Buffer classes. None of these existing
	approaches to abstracting sources of input can be used to wrap/represent
	each other directly, which is why IInputs were created.
	
	IInputs also allow for the controlling or "bounding" of accessible data from
	an underlying source as well as automatically filling the read buffer from
	the underlying source (regardless of type) making IInputs incredibly ease to
	use as extremely efficient input sources. 
	
	* IInput implementations are as efficient as the most efficient read operations
	from InputStream or NIO Buffer classes in that you get direct access to the
	read buffer used by the stream to pull in data from it's underlying source;
	there is no need to copy the contents to a second construct for use.
	
	* Default IInput implementations provided for all popular sources:
		* InputStreamInput	java.io.InputStream source with byte[] buffer
		* ReaderInput		java.io.Reader source with char[] buffer
		* ByteArrayInput	byte[] source with byte[] buffer
		* CharArrayInput	char[] source with char[] buffer
		* ByteBufferInput	java.nio.ByteBuffer source with byte[] buffer
		* CharBufferInput	java.nio.CharBuffer source with char[] buffer
		* CharSequenceInput	java.lang.CharSequence source with char[] buffer

2.1
	* Added AbstractRetryableTask; an Callable<V> implementation that can 
	automatically retry failed tasks up to a configurable amount of times, 
	sleeping the executing Thread a configurable (increasing) duration every 
	subsequent time the task fails. This is fantastic for cloud-based/API or 
	data-store operations that may frequently fail and retrying them is not
	uncommon (e.g. Using Amazon Web Services APIs).

2.0
	* Fixed bug in build script where library required Java 6. It now works under
	Java 5 now.
	
	* Added RandomUtils class. Convenience methods for generating random numeric
	and character values (e.g. for password or unique file names).
	
	* Added ArrayUtils "NoCheck" methods for all major index searches and equals
	methods. These methods do NO pre-condition check. Handy when the utils class
	is being used inside of another utils class that does all the pre-condition
	checking already and don't want to incur any overhead.
	
	* Added ArrayUtils.append methods
	
	* Added ArrayUtils.insert methods
	
	* Added ArrayUtils.indexAfter methods to find the first index after the given
	value(s). Essentially skipping all values in array that match the value list
	provided, and finding the first non-matching index after the group.
	
	* Modified the ordering of arguments in library to more closely match the
	sequence implied by language.
	
	For example, when you see the method "indexOf(char c, chars[] array, int i)"
	you can read that out loud as: "Find the indexOf 'c', in 'array' starting
	at index 'i'".
	
	Previously the ordering was arbitrary and non-uniform across the library. To
	help improve the intuitiveness of the library and unify the style, it was
	changed.
	
	* Test coverage for all new methods and classes added.
	
	* Integrated into production in the CloudFront Log Parser project.
	http://www.thebuzzmedia.com/software/cloudfront-log-parser/
	
	* Integrated into production in the common-parser-lib project.
	http://www.thebuzzmedia.com/software/common-parser-lib-common-parser-java-utility-library/

1.1
	* ArrayUtils additions
		- equals
		- ensureCapacity
		- all methods apply to both byte[] and char[]
		
	* Charset util additions
		- Added DecodingUtils
		- Added EncodingUtils
	
	* Added test cases for all new methods and classes.

1.0
	* Initial public release.


License
-------
This library is released under the Apache 2 License. See LICENSE.


Description
-----------
A collection of hand-tuned, low-overhead classes used by most of the open source
and commercial software from The Buzz Media.

Many of the operations performed by this library (like searching an array for
a byte or char, or parsing a non-float number) are performed by other libraries
readily available from projects like Apache Commons; this functionality is
re-implemented in this library with a tight focus on performance and lower 
memory overhead at the expense of code duplication.

What that means is avoiding extremely deep method call-hierarchies for something
like indexOf(char[], char) calling down into a more specific method, then
another and another and another until finally ending up at some Abstract class
base implementation.

Benchmarks are provided to compare the library's performance to that of more
"standard" methods.


Performance
-----------
Benchmarks can be found in the /src/test/java folder and can be run directly
from the command line (no need to setup JUnit).

[Platform]
* Java 1.6.0_24 on Windows 7 64-bit 
* Dual Core Intel E6850 processor
* 8 GB of ram

[Benchmark Results]
indexOf byte		elapsed time: 12ms	(3,328,000 bytes scanned)
indexOf byte[]		elapsed time: 22ms	(3,328,000 bytes scanned)
indexOfAny byte[]	elapsed time: 23ms	(3,328,000 bytes scanned)

JDK Integer.parseInt 			elapsed time: 72ms	(1310720 numbers parsed, 6553600 bytes processed)
common-lib NumberUtils.parseInt elapsed time: 55ms	(1310720 numbers parsed, 9175000 bytes processed)


** A note about the Integer.parseInt comparison; the time required to read in the
sample file, decode it from byte[] to char[] and then convert those all into
String instances IS NOT INCLUDED in the benchmark timing. If you were to include
that, you would see both the  memory usage and CPU time of using 
Integer.parseInt to be significantly higher than NumberUtils.parseInt.


Runtime Requirements
--------------------
None.

There are currently no 3rd party dependencies required to use common-lib.


History
-------
While working on a few disparate projects (high performance XML parser,
Redis DB driver, CloudFront log parser, etc.) I noticed a pattern in the types
of utilities I was writing over and over again OR logic I was inlining directly
in my code.

I generalized this code and broke it out into this library so the handful of
projects maintained by The Buzz Media could more easily make use of the code.

I decided to open source the project because there is no proprietary magic in
any of this, the library is tuned to be fast with a small memory footprint and
I thought others might find it handy as opposed to using more bloated libs like
Apache Commons.


Contact
-------
If you have questions, comments or bug reports for this software please contact
us at: [email protected]