Monday, December 31, 2012

SoftHashMap - hashmap with soft values


The biggest problem with WeakHashMap is, it will only weakly reference the keys but not the values. This may lead to memory issues if we are using weakhashmap as a cache.

We can try this!!



import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;



public class SoftHashMap<K, V> extends AbstractMap<K, V> {

/** The internal HashMap that will hold the SoftReference. */
private final Map<K, SoftValue<V>> hash = new HashMap<K, SoftValue<V>>();

/** The number of "hard" references to hold internally. */
private final int HARD_SIZE;

/** The FIFO list of hard references, order of last access. */
private final LinkedList<V> hardCache = new LinkedList<V>();

/** Reference queue for cleared SoftReference objects. */
private final ReferenceQueue queue = new ReferenceQueue();

public SoftHashMap() {
this(150);
}

public SoftHashMap(int hardSize) {
HARD_SIZE = hardSize;
}

public V get(Object key) {
V result = null;
// We get the SoftReference represented by that key
SoftReference<V> soft_ref = hash.get(key);
if (soft_ref != null) {
// From the SoftReference we get the value, which can be
// null if it was not in the map, or it was removed in
// the processQueue() method defined below
result = soft_ref.get();
if (result == null) {
// If the value has been garbage collected, remove the
// entry from the HashMap.
hash.remove(key);
} else {
// We now add this object to the beginning of the hard
// reference queue. One reference can occur more than
// once, because lookups of the FIFO queue are slow, so
// we don't want to search through it each time to remove
// duplicates.
hardCache.addFirst(result);
if (hardCache.size() > HARD_SIZE) {
// Remove the last entry if list longer than HARD_SIZE
hardCache.removeLast();
}
}
}
return result;
}

/**
* We define our own subclass of SoftReference which contains not only the
* value but also the key to make it easier to find the entry in the HashMap
* after it's been garbage collected.
*/
private static class SoftValue<V> extends SoftReference<V> {
private final Object key; // always make data member final

private SoftValue(V obj, Object key, ReferenceQueue queue) {
super(obj, queue);
this.key = key;
}
}

/**
* Here we go through the ReferenceQueue and remove garbage collected
* SoftValue objects from the HashMap by looking them up using the
* SoftValue.key data member.
*/
private void processQueue() {
SoftValue sv;
while ((sv = (SoftValue) queue.poll()) != null) {
hash.remove(sv.key); // we can access private data!
}
}

/**
* Here we put the key, value pair into the HashMap using a SoftValue
* object.
*/
public V put(K key, V value) {
processQueue(); // throw out garbage collected values first
SoftValue<V> softValue = new SoftValue<V>(value, key, queue);
SoftValue<V> put = hash.put(key, softValue);
if (put != null) {
return put.get();
}
return null;
}

public V remove(Object key) {
processQueue(); // throw out garbage collected values first
SoftValue<V> remove = hash.remove(key);
if (remove != null)  {
return remove.get();
}
return null;
}

public void clear() {
hardCache.clear();
processQueue(); // throw out garbage collected values
hash.clear();
}

public int size() {
processQueue(); // throw out garbage collected values first
return hash.size();
}

public Set entrySet() {
throw new UnsupportedOperationException();
}
}

Eclipse author ${user} variable



Here is a small “hack” which can put anything you want in this ${user} variable.

Add one more variable in the eclipse.ini file with the following.
-vmargs 
-Duser.name="your name here..." 

or
Rather than having to change the template manually, add 
-vmargs -Duser.name="your name here" to the shortcut you use to run Eclipse ( by right clicking on it, selecting properties and editing the target input field) :
C:/java/eclipse/eclipse.exe -vmargs -Duser.name="your name here.."

Sunday, December 30, 2012

Force overwrite on git pull

How do I force an overwrite of local files on a git pull?


git fetch --all
git reset --hard origin/master
git fetch downloads the latest from remote without trying to merge or rebase anything. 
Then thegit reset resets the master branch to what you just fetched

Thursday, December 27, 2012

Image decorator






Here is the simple snippet to add a decorator to the image.



@Override
public Image getImage(Object element) {


if (resource instanceof Column)
{
 return decorateImage(SImageRegistry.getImage(SImageConstants.column), element);
}

}


public Image decorateImage(Image image, Object element) {
if (element instanceof Column) {
if (((Column) element).isPrimaryKeyPart()) {
DecorationOverlayIcon decorationOverlayIcon = new DecorationOverlayIcon(image,
SImageRegistry.getImageDescriptor(SImageConstants.primary_key), IDecoration.TOP_LEFT);
return decorationOverlayIcon.createImage();
}
return image;
}
return null;
}

Wednesday, December 5, 2012

Increase heap size to your eclipse

Here is the example to specify the eclipse vm arguments in eclipse.ini file to avoid eclipse memory issues during your development.

-startup
plugins/org.eclipse.equinox.launcher_1.0.100.v20080501.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.100.v20080428-1330
-showsplash
org.eclipse.platform
-vm
/usr/lib/jvm/java-1.5.0-sun/jre/bin/java
-vmargs
-Xms512m
-Xmx1024m
-XX:+UseParallelGC
-XX:PermSize=512M
-XX:MaxPermSize=1024M

If you are working with eclipse plug-in development, while launching your eclipse application you have to specify the vm arguments so that it will be available for your target platform as well.
Please find the screenshot below to configure it.









Wednesday, November 28, 2012

Collections emptyList()

Can you guess the output for the below program ?
import java.util.Collections;
import java.util.List;

public class CollectionsTest {

private List<String> pool = Collections.<String> emptyList();

public List<String> call1() {
pool.add("Hello");
return pool;
}

public static void main(String[] args) {
CollectionsTest collectionsTest = new CollectionsTest();
List<String> call1 = collectionsTest.call1();
System.out.println(call1);
call1.add("one more added..");
System.out.println(call1);
}
}


Output:

Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:131)
at java.util.AbstractList.add(AbstractList.java:91)
at CollectionsTest.call1(CollectionsTest.java:9)
at CollectionsTest.main(CollectionsTest.java:15)


In short:
Collections.emptyList() returns an immutable list, i.e., a list to which you cannot add or remove elements.

Then, why should we use at all ? What is the purpose of this ?


Best Regards,
Kondal Kolipaka


My JAXB Learnings - Part 2


As part of this post, you will be understanding on the following concepts in the JAXB through an example.

1. Defining the name space
2. Defining the wrapper elements in the XML
3. Setting the name for entities in the list.
4. Defining the order for elements

This example is based on the book store and book model objects.

Book.java


import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "myBook")
// If you want you can define the order in which the fields are written
// Optional
@XmlType(propOrder = { "author", "name", "publisher", "isbn" })
public class Book {

private String name;
private String author;
private String publisher;
private String isbn;

// If you like the variable name, e.g. "name", you can easily change this
// name for your XML-Output:
@XmlElement(name = "titleName")
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public String getPublisher() {
return publisher;
}

public void setPublisher(String publisher) {
this.publisher = publisher;
}

public String getIsbn() {
return isbn;
}

public void setIsbn(String isbn) {
this.isbn = isbn;
}

}



2. BookStore.java


import java.util.ArrayList;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

//This statement means that class "Bookstore.java" is the root-element of our example
@XmlRootElement(namespace = "com.kondal.bookstore.model")
public class BookStore {

// XmLElementWrapper generates a wrapper element around XML representation
@XmlElementWrapper(name = "bookList")

// XmlElement sets the name of the entities
@XmlElement(name = "book")
private ArrayList<Book> bookList;
private String name;
private String location;

public void setBookList(ArrayList<Book> bookList) {
this.bookList = bookList;
}

public ArrayList<Book> getBooksList() {
return bookList;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getLocation() {
return location;
}

public void setLocation(String location) {
this.location = location;
}
}


3. BookMain 


import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class BookMain {

private static final String BOOKSTORE_XML = "./BookStore-jaxb.xml";

public static void main(String[] args) throws JAXBException, IOException {

ArrayList<Book> bookList = new ArrayList<Book>();

// create books
Book book1 = new Book();
book1.setIsbn("978-0060554736");
book1.setName("The Game");
book1.setAuthor("Neil Strauss");
book1.setPublisher("Harpercollins");
bookList.add(book1);

Book book2 = new Book();
book2.setIsbn("978-3832180577");
book2.setName("Feuchtgebiete");
book2.setAuthor("Charlotte Roche");
book2.setPublisher("Dumont Buchverlag");
bookList.add(book2);

// create BookStore, assigning book
BookStore BookStore = new BookStore();
BookStore.setName("Fraport BookStore");
BookStore.setLocation("Frankfurt Airport");
BookStore.setBookList(bookList);

// create JAXB context and instantiate marshaller
JAXBContext context = JAXBContext.newInstance(BookStore.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

// Write to System.out
m.marshal(BookStore, System.out);

// Write to File
m.marshal(BookStore, new File(BOOKSTORE_XML));

// get variables from our xml file, created before
System.out.println();
System.out.println("Output from our XML File: ");
Unmarshaller um = context.createUnmarshaller();
BookStore bookstore2 = (BookStore) um.unmarshal(new FileReader(
BOOKSTORE_XML));
ArrayList<Book> list = bookstore2.getBooksList();
for (Book book : list) {
System.out.println("Book: " + book.getName() + " from "
+ book.getAuthor());
}
}
}


Output on console:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:bookStore xmlns:ns2="com.kondal.bookstore.model">
    <bookList>
        <book>
            <author>Neil Strauss</author>
            <titleName>The Game</titleName>
            <publisher>Harpercollins</publisher>
            <isbn>978-0060554736</isbn>
        </book>
        <book>
            <author>Charlotte Roche</author>
            <titleName>Feuchtgebiete</titleName>
            <publisher>Dumont Buchverlag</publisher>
            <isbn>978-3832180577</isbn>
        </book>
    </bookList>
    <location>Frankfurt Airport</location>
    <name>Fraport BookStore</name>
</ns2:bookStore>

Output from our XML File:
Book: The Game from Neil Strauss
Book: Feuchtgebiete from Charlotte Roche