Wednesday, September 25, 2013

Wicket 6 - Disable Page Serialization

In some cases it makes sense to disable Page Serialization, this can be archived by registering empty Page Store:

public class WicketWebApplication extends WebApplication {

    @Override 
    public Class<? extends Page> getHomePage() {
        return CqlCommanderPage.class; 
    } 

    @Override 
    protected void init() {
        super.init(); 
        setPageManagerProvider(new NoSerializationPageManagerProvider(this));
    } 
}
public class NoSerializationPageManagerProvider extends DefaultPageManagerProvider {

    public NoSerializationPageManagerProvider(Application application) {
        super(application); 
    } 

    @Override 
    protected IPageStore newPageStore(IDataStore dataStore) { 
        return new IPageStore() {
            @Override 
            public void destroy() {
            } 

            @Override 
            public IManageablePage getPage(String sessionId, int pageId) {
                return null;
            } 

            @Override 
            public void removePage(String sessionId, int pageId) {
            } 

            @Override 
            public void storePage(String sessionId, IManageablePage page) {
            } 

            @Override 
            public void unbind(String sessionId) {
            } 

            @Override 
            public Serializable prepareForSerialization(String sessionId, Object page) {
                return null;
            } 

            @Override 
            public Object restoreAfterSerialization(Serializable serializable) {
                return null;
            } 

            @Override 
            public IManageablePage convertToPage(Object page) {
                return null;
            } 
        }; 

    } 
}

Wednesday, July 17, 2013

Spring 3.1 - Programmatic access to Properties managed by Property Placeholder

Spring follows Inversion Of Control approach, this means that we can simply inject particular property into POJO. But there are some cases, when you would like to access property given by name directly from your code - some might see it as anti-pattern - this is palpably true, but lets concentrate on how to do it.
The PropertiesAccessor below provides access to properties loaded by Property Placeholder and encapsulates container specific stuff. It also caches found properties because call on AbstractBeanFactory#resolveEmbeddedValue(String) is not cheap.
@Named
public class PropertiesAccessor {

    private final AbstractBeanFactory beanFactory;

    private final Map<String,String> cache = new ConcurrentHashMap<>();

    @Inject
    protected PropertiesAccessor(AbstractBeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public  String getProperty(String key) {
        if(cache.containsKey(key)){
            return cache.get(key);
        }

        String foundProp = null;
        try {
            foundProp = beanFactory.resolveEmbeddedValue("${" + key.trim() + "}");
            cache.put(key,foundProp);
        } catch (IllegalArgumentException ex) {
           // ok - property was not found
        }

        return foundProp;
    }
}

Saturday, June 8, 2013

Linux - search for text occurrences in files specified by pattern

Script below searches for files given by pattern (*.java)  containing given key word (case insensitive). It starts from current directory and goes over all sub-directories.
Produced output is divided into sections - one per matching file.
Each section lists key word occurrences within particular file, inclusive line numbers and highlighting.

Create file "se" with following content:
#!/bin/sh
find ${PWD} -name $1  -exec grep --color='auto' -ni $2 '{}' \; -printf '\n\n\n%h-%f\n'

Now in order to find *.java files containing text "nullpointer" execute:
se *.java nullpointer

search result could look like this one:


Thursday, February 7, 2013

Efficient mapping of Java Enums

The idea is to create Enum out of some other type like string or int - this is the method valueOfRole in examples below. I've seen few code examples which are based on this approach:
public enum RoleWithLoop {
    SU(0), ADMIN(1), USER(1000);

    private final int state;

    RoleWithLoop(int state) {
        this.state = state;
    }

    public static RoleWithLoop valueOfRole(int state) {
        for (RoleWithLoop role : RoleWithLoop.values()) {
            if (role.state == state) {
                return role;
            }
        }
        return null;
    }
}
Each mapping call iterates over all Enum entries - this is fine if it contains only few elements. But more efficient solution is to use Map lookup instead of loop:
public enum RoleWithMap {
    SU(0), ADMIN(1), USER(1000);

    private final int state;

    private final static Map<Integer, RoleWithMap> MAPPING = 
          new HashMap<Integer, RoleWithMap>(RoleWithMap.values().length);
    RoleWithMap(int state) {
        this.state = state;
    }

    static {
        for (RoleWithMap role : RoleWithMap.values()) {
            MAPPING.put(role.state, role);
        }
    }

    public static RoleWithMap valueOfRole(int state) {
        return MAPPING.get(state);
    }
}


Tuesday, November 27, 2012

Ubuntu - German Characters on English Keyboard

I have two keyboards - USA and UK. I prefer those over German keyboard due to brackets location. The idea is to access German characters with following key combinations:
  • Right ALT + s -> ß
  • Right ALT + a -> ä
  • Right ALT + o -> ö
  • Right ALT + u -> ü

This can be achieved with xmodmap. Just create in your home directory file called .Xmodmap and copy content below into it.


For USA keyboard:
keycode 108 = ISO_Level3_Shift ISO_Next_Group ISO_Level3_Shift ISO_Nexkt_Group
keycode  30 = u U u U udiaeresis Udiaeresis
keycode  32 = o O o O odiaeresis Odiaeresis
keycode  38 = a A a A adiaeresis Adiaeresis
keycode  39 = s S s S ssharp

For UK keyboard:
keycode 108 =  Mode_switch Mode_switch Mode_switch
keycode  30 = udiaeresis Udiaeresis u U udiaeresis Udiaeresis
keycode  32 = odiaeresis Odiaeresis o O odiaeresis Odiaeresis
keycode  38 = adiaeresis Adiaeresis a A adiaeresis Adiaeresis
keycode  39 = ssharp ssharp s S s S ssharp

You can also manually load key bindings by executing xmodmap .Xmodmap





Sunday, November 25, 2012

Ubuntu - Setup Kate Editor to Open Each Document in new Window

By default Kate opens documents within single editor. In order to open each document in new Kate editor execute following commands:

printf '#!/bin/bash\n/usr/bin/kate_org -n "$@"' > kate
chmod +x kate
sudo mv /usr/bin/kate /usr/bin/kate_org
sudo mv kate /usr/bin/

Wednesday, September 5, 2012

Cassanrda 1.1 - Tuning for Frequent Column Updates

Cassandra is known for its good write performance, but there are scenarios, when you might run into trouble - especially when particular use case generates heavy disk IO. This could be the case for columns which receive frequent updates. However you can avoid those problems, with proper configuration, or just by updating to recent Cassandra version. The good news is, that it can be applied to already ruining system, so when you are already having problems, there is still a hope.

Memtables are flushed to immutable SSTables, and it is possible, that single column value can be stored in different SSTables, when its value was changing over long enough time period. This guarantees fast inserts, because data is being just appended to disk. But on the other hand, unnecessary writes will decrease disk performance, not only because many SSTables has to be written, but mainly because duplicates on disk will have to be compacted later on.

The idea is to tune Cassandra in the way, that we take benefit from frequent updates. This can be achieved by keeping data in memory and by delaying disk flushes. In this case new updates will replace existing values in memory.
This will generate less disk traffic, because it will decrease amount of flushed duplicates. This is not all - this will also create write through cache, and read requests will benefit from it. Here are some confutation tips:
  • Make sure that you have at least Cassandra 1.1 - it contains optimization for frequently changing values (CASSANDRA-2498). For the cases where single value is stored in multiple SSTables, older Cassandra versions would need to read column values from all SSTables in order to find most recent one. Now SSTables are sorted by modification time, so it's enough to read most recent value and simply ignore remaining outdated values.
  • Increase thresholds for flushing memtables. Each update on memtable, results in one less entry in SSTable.
  • Each read operation checks first memtables, if data is still there, it will be simply returned - this is the fastest possible access. Its like non blocking write through cache (based on skip list).
  • To large memtable on the other hand will result in larger commit log. This is not a problem, until your instance crashes. It will need some time to start, because it would need to read whole commit log.
  • Compaction merges SSTables together, and this increases read performance, since we have less data to go through. But this process does not have high priority. When Cassandra is nearly exhausted, it will skip compaction, and this can lead to data fragmentation.
Caching:
  • Row cache makes really sense for frequent reads of the same row(s), and additionally when you read most of the columns of each single row.
  • For active row cache, access to single column from particular row will load whole row with all its columns into memory. Analyze data access patterns, and makes sure that it is not an overhead, and that you have enough memory. It would be really waste of resources, to load million columns into memory, to just access only a few.
  • Row cache works as wright through, for data that is already in it. Data is loaded into row cache first when it's being read, and when it was not found in memtable. From this point of time it will get updated on each write operation. Frequently changing entry, without read access will not affect row cache, because it's not there.
  • Updates on data in row cache will decrease performance, and actually, those frequently changing columns are probably also available in memtable. Read process will first search memtable, and in case of hit ignore row cache. From this point of view row cache makes sense, if you also read other columns which are not changing frequently. For example single row has 200 columns, 50 receive frequent updates, 100 sporadic, and read process reads always all. In this case row cache makes sense - we will have to actualize 50 columns on each insert, but we will gain fast access to remaining 150.
  • It might be good idea to disable row cache, increase memtable size in hope to reduce disk writes, and to use memtable as cache.
  • Disabling row cache does not necessary mean additional disk seeks. Cassandra uses memory mapped files, which means that each file access is being cached by operating system. Relaying on memory mapped files is nothing new - Mongo does not have cache at all - it's not needed, since file system cache works just fine. But Mongo has different data structure on hard drive, because they store BSON document optimized for reads, its all in one place, Cassandra might (not always) need first to collect data from different locations.
  • Row cache would help also in situation where single row spreads over many SSTables. In this case putting all data together is CPU intensive operation, not mentioning possible disk access to read each column value.
  • When row cache is disabled, key cache must be used. Key cache is like an index - and you definitely want to load your whole index into memory.
  • When row cache is disabled and key cache is enabled, and read operation get hits on key cache, we have quiet performant solution. Searching SSTables runs fully in memory, only reading column value itself requires disk access. And maybe even not that, since it's memory mapped file.
  • When disabling row cache remember to tune read ahead. The idea is, to read from disk only single column and not more data when it's not needed.
Just to summary.... run performance tests, check Cassandra statistics, and verify how many SSTables has to be searched to find data, and what is the cache usage. This might be good entry point to change memtable size, or to tune caching. In my case disabling row cache, large key cache and increased memtable thresholds was the right decision.