Archive

Archive for the ‘Uncategorized’ Category

Towards a scalable Bloom filter

August 7, 2016 Leave a comment

Recently I have given the tool „jdeps” a test ride. It’s a tool that is included with Java 8 and extracts packet dependencies of usual java code from jar files, classes, etc. It turned out that the Trove library that we ship with our application was used in very few places and considering the number of usages and its size after signing, did not seem worth the download for the customer.
So I replaced it where possible and came across our ID-manager class, that would hold a couple of long values in a TlongHashSet, and replacing gnu.trove.TLongHashSet with java.util.HashSet meant wrapping all those longs in Objects. That would waste quite some space. Being cautious I tested this change with the outrageous number of about 5 million IDs, just to see how memory consumption compares in the extreme. The result was interesting: TlongHashSet used about 116 megabytes and java.util.HashSet used about 339 megabytes of RAM to store these 5 million IDs. This number of IDs is not something we’d expect to happen in the real world and more realistic numbers suggest that while java.util.HashSet may be a viable solution, it’s still considerably more wasteful than TlongHashSet and memory should be used for better things. Unfortunately the ID manager is also restricted to long values; relaxing that constraint didn’t look like bad idea in the long run. The ID-manager’s job is to generate new IDs and it should pick the shortest one it can find, so the numbers don’t grow too large to keep file sizes low. It just needs to know if an ID is definitely not in use, but it is okay to mistakenly assume an ID is in use, while it’s not. It would be nice if IDs could be alphanumeric. This is a classic case for a Bloom filter. I thought about it for a while and decided that, due to the rather small amount of IDs that we use in our system, it wasn’t worth adding the code to our project and got on with more important things. But sometimes work haunts me. Back at home I could not get this Bloom filter idea out of my head, so I set out to explore this data structure. Read more…

Hack of the day: Get a method-annotation’s default value

June 27, 2016 Leave a comment

So you have an annotation like this:

@Inherited
@Documented
@InterceptorBinding
@Retention(RUNTIME)
@Target({ METHOD, TYPE, FIELD })
public @interface Logged {

	@Nonbinding
	String value() default "debug";

	@Nonbinding
	String detailValue() default "trace";

}

But the source code is not under your control, so you can’t refactor it to use a public constant. How will you get any annotation method’s default value?
You could do it like this:

private String badWay() {
	final Method meth = Logged.class.getMethod("detailValue");
	final Logged annotation = meth.getAnnotation(Logged.class);
	return Level.valueOf(annotation.value());
}

But then, if someone from the outside refactored it and renamed the method, your compiler won’t notice and it will break at runtime, which is bad.
Here’s a way to perform the task with some introspection, given the annotation can be used on methods:

Logged defaultLogged; //lazily initialized, as reflection is slow

@Logged // annotation with default log level
private String defaultAnnotationDetailLogLevel() {
        if(defaultLogged == null}{
            class Local {};
            final Method meth = Local.class.getEnclosingMethod(); // this method
            defaultLogged = meth.getAnnotation(Logged.class);
        }
        return defaultLogged.detailValue();
}

In case the annotation will be changed to use any other method name, your compiler will notice immediately and you can fix the broken code before it slips through testing and hits production. Nifty!

Don’t handle just another state if you can query, please!

April 14, 2010 2 comments

How often do you find yourself having trouble to understand a big chunk of code? At the moment I’m pretty busy with refactoring just another controller. Even though the number of WTF/min from my office is quite large at the moment, I’m not angry with the fellows who wrote it. The code was made under time pressure and as far as I’m informed, people were under constant threat to be criticized for introducing a bug by changing working code for no apparent reason. Unfortunately refactoring and code cleanups are sometimes hard to sell as “apparent reason”, especially to non-technical staff. As a result code quality starts to decay, changes take longer than necessary and refactoring gets harder every day. I’m placing my bet on my “new kid on the block” credits to go for the risk of breaking code at the moment. So what’s making my life hard at the moment? State! Read more…

Categories: Uncategorized Tags: ,