Yet another Java Developer.

JSF Developer living in Oklahoma City

Gallery

1239504168646.jpg IMGP0165.JPG 1239164612590.jpg IMGP0078.JPG

org.hibernate.HibernateException: The chosen transaction strategy requires access to the JTA TransactionManager

While setting up a simple web app on JBoss 5 using container manager transaction I run into following exception

Caused by: org.hibernate.HibernateException: The chosen transaction strategy requires access to the JTA TransactionManager
	at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:361)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327)

Well after some research I figured out that the cause of this were two simple configuration options in persistence.xml


First we need to make sure we are using JTA as transaction-type (by default)

  <persistence-unit name="PU_NScaffold" transaction-type="JTA">



Second make sure we have following line under properties node

  <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>





Thats it, I hope this helps someone.

Preventing ViewExpiredException in JSF

When our page is idle for x amount of time the view will expire and throw javax.faces.application.ViewExpiredException to prevent this from happening
one solution is to create CustomViewHandler that extends ViewHandler
and override restoreView method all the other methods are being delegated to the Parent

import java.io.IOException;
import javax.faces.FacesException;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
 
public class CustomViewHandler extends ViewHandler {
	private ViewHandler parent;
 
	public CustomViewHandler(ViewHandler parent) {
		//System.out.println("CustomViewHandler.CustomViewHandler():Parent View Handler:"+parent.getClass());
		this.parent = parent;
	}
 
    @Override public UIViewRoot restoreView(FacesContext facesContext, String viewId) {
	/**
	 * {@link javax.faces.application.ViewExpiredException}. This happens only  when we try to logout from timed out pages.
	 */
	UIViewRoot root =null; 
	root = parent.restoreView(facesContext, viewId);
	if(root == null) {			
		root = createView(facesContext, viewId);
	}
	return root;
 }
 
 @Override
	public Locale calculateLocale(FacesContext facesContext) {
		return parent.calculateLocale(facesContext);
	}
 
	@Override
	public String calculateRenderKitId(FacesContext facesContext) {
		String renderKitId = parent.calculateRenderKitId(facesContext);
		//System.out.println("CustomViewHandler.calculateRenderKitId():RenderKitId: "+renderKitId);
		return renderKitId;
	}
 
	@Override
	public UIViewRoot createView(FacesContext facesContext, String viewId) {
		return parent.createView(facesContext, viewId);
	}
 
 
    @Override
	public String getActionURL(FacesContext facesContext, String actionId) {
		return parent.getActionURL(facesContext, actionId);
	}
 
	@Override
	public String getResourceURL(FacesContext facesContext, String resId) {
		return parent.getResourceURL(facesContext, resId);
	}
 
	@Override
	public void renderView(FacesContext facesContext, UIViewRoot viewId) throws IOException, FacesException {
		parent.renderView(facesContext, viewId);
 
	}
 
	@Override
	public void writeState(FacesContext facesContext) throws IOException {
		parent.writeState(facesContext);
	}
 
	public ViewHandler getParent() {
		return parent;
	}
 
}

Then you need to add it to your faces-config.xml

<view-handler>com.demo.CustomViewHandler</view-handler>

This will prevent you from getting ViewExpiredException’s

Use argument in EL expression

There is couple ways about doing that, you could use JBoss EL expression implementation they support method calls with parameters check out Seam, or use similar approach as @digitaljoel suggested.
This is what I created for that purpose, you can call static and static methods, not a great solution but it does the job.

    <c:if  test="#{t:call(null, '@Util.SecurityUtility', 'isPanelWorkbookEnabledForUser','')}">
          Hello Panel    
      </c:if>

@Util is just an alias to com.mycomp.util where

**Example 2**

    <c:if test="#{item != null and  t:call(item, 'java.lang.String', 'indexOf', t:params(t:param('flash-alert',''))) == 0}">                
        #{t:call(session, 'org.apache.catalina.session.StandardSessionFacade', 'removeAttribute', t:params(t:param(item,'')))}      
    </c:if>

t:call, t:params, t:param are function defined in project-taglib.xml as so

    	<function>
		<function-name>call</function-name>
		<function-class>util.Functions</function-class>
		<function-signature>java.lang.Object call(java.lang.Object, java.lang.String, java.lang.String, java.lang.Object[])</function-signature>
	</function>
	<function>
		<function-name>param</function-name>
		<function-class>.util.Functions</function-class>
		<function-signature>java.lang.String param(java.lang.Object, java.lang.String)</function-signature>
	</function>	
 
	<function>
		<function-name>params</function-name>
		<function-class>util.Functions</function-class>
		<function-signature>java.lang.Object[] params(java.lang.String)</function-signature>
	</function>

Here is the implementation

    package mycompany.web.util;
 
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
 
import javax.el.MethodNotFoundException;
 
 
public class Functions {
 
	private  static HashMap<String, String> alliasMap;
	static{
		alliasMap=new HashMap<String, String>();
		alliasMap.put("@DateUtil", "com.americanbanksystems.compliance.util.DateUtil");
		//Match anything following the dot(.)
		alliasMap.put("@Util.*", "com.americanbanksystems.compliance.util");
 
		alliasMap.put("@Application.*", "com.americanbanksystems.compliance.application");
 
	}
 
 
 
 
	public static String param(Object obj, String cls) {	
		//make sure that passed in object is not null
		if(obj==null){
			obj="";
		}
 
		ByteArrayOutputStream baut=new ByteArrayOutputStream();
		XMLEncoder encoder=new XMLEncoder( baut );
		//Bug in the JDK
		//http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=c993c9a3160fd7de44075a2a1fa?bug_id=6525396
		if(obj instanceof java.sql.Timestamp){
			Date o = new Date(((java.sql.Timestamp)obj).getTime());
			obj=o;
		}		
		//Checking if this is possible 
		if(String.class.isAssignableFrom(obj.getClass())){
			//removed trailing +" " because it was causing indexOf return invalid value
			//Unknown side effects
			obj=FacesUtil.get(obj.toString());			
		}
			encoder.writeObject( obj );
		encoder.close();
		return new String(baut.toByteArray());
	}
 
	private static Object decode(String str){
		ByteArrayInputStream bais=new ByteArrayInputStream(str.getBytes());
		XMLDecoder decoder=new XMLDecoder(bais);
		return decoder.readObject();
	}
 
	public static Object[] params(String str){
		// (?<=</java>)\s*(?=<?)
		String[] obj=str.split("(?<=</java>)\\s*(?=<?)");
		Object[] results=new Object[obj.length];
		for(int i=0;i<obj.length;i++){
			results[i]=decode(obj[i]);
		}
		return results;
	}
 
 
	@SuppressWarnings("unchecked")
	public static Object call(Object owningObject, String qualifiedClassname, String methodName, java.lang.Object... methodArguments) {
		if (null == methodName || methodName.equals("")) {
			throw new IllegalArgumentException("Method name can't be null or empty");
		}
		if (null == methodArguments) {
			methodArguments = new Object[0];
		}
 
		//Check for aliases 
		if(qualifiedClassname.indexOf("@")>-1){
			String subpackage=qualifiedClassname;
			String originalClass=qualifiedClassname;
			//Split at the dot
			boolean isPackageAllias=false;
			String[] sp=subpackage.split("\\.");	
			if(sp.length>1){
				subpackage=sp[0]+".*";
				isPackageAllias=true;
			}
			if(alliasMap.containsKey(subpackage)){
				String value = alliasMap.get(subpackage);
				if(isPackageAllias){
					qualifiedClassname=subpackage.replace(sp[0], value);
					qualifiedClassname=qualifiedClassname.replace(".*", originalClass.replace(sp[0],""));
				}else{
					qualifiedClassname=value;
				}
			}else{
				throw new IllegalArgumentException("Allias name '"+qualifiedClassname+"' not found");
			}
		}
		Class clazz;
		try {
			clazz = Class.forName(qualifiedClassname);
			//Find method by methodName,Argument Types
			Class[] argumentTypes=new Class[methodArguments.length];	
 
			for(int i=0;i<methodArguments.length;i++){
				argumentTypes[i]=methodArguments[i].getClass();
				//Check if the passed in method argument is a string and if its represented as unicode char				
				//if it is then convert it into a char and reassign to the original parameter
				//example 1:  \u0022 == "
				//example 2:  \u0027 == '
				// Reason for this functionality is that we can't pass " and ' from within t:call method
				if (argumentTypes[i] == String.class && methodArguments[i].toString().indexOf("\\u") > -1) {
					String arg = methodArguments[i].toString();
					arg = arg.substring(2, arg.length());
					try {
						int outchar = Integer.parseInt(arg, 16);
						if (Character.isDefined(outchar)) {
							methodArguments[i] = String.valueOf((char) outchar);
						}
					} catch (NumberFormatException nfe) {
						// Suppress error and continue assuming this is a regular string
					}
				}
			}
 
			Method methodToInvoke = null;
			try{
				methodToInvoke  = clazz.getMethod(methodName, argumentTypes);
			}catch(NoSuchMethodException nsm){//Find by method name/ argument count
				for (Method method : clazz.getMethods()) {
					if (method.getName().equals(methodName)  && method.getParameterTypes().length == methodArguments.length) {
						if (null == owningObject) {
							owningObject = clazz.newInstance();
						}
						methodToInvoke=method;
						break;
					}
				}
			}
 
			if(methodToInvoke!=null){								
				return methodToInvoke.invoke(owningObject, methodArguments);
			}else{
				throw new InstantiationException("method not found :" + methodName);	
			}
 
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}
		return null;
	}
 
 
	public static void main(String[] arg) {
		// StringBuffer buff=new StringBuffer();
		// buff.append("Gregs init");
		// Functions.call(java.lang.Class<T>, T, java.lang.String, java.lang.String, java.lang.Object...)
		/*
		 * Functions.call(StringBuffer.class, buff, "java.lang.StringBuffer","append"," Init ");
		 * Functions.call(StringBuffer.class, buff, "java.lang.StringBuffer","append"," greg ");
		 * System.out.println("output="+ buff);
		 */
 
		//#{t:call(null, ".util.DateUtil", "normalizeDate", t:parametize(editRiskActionPlan.riskActionPlan.completionDate,",","java.lang.Object"))}
	//	c(call(null, "util.DateUtil", "normalizeDate", new Date()));
 
		//	#{t:parametize(editRiskActionPlan.riskActionPlan.completionDate,",","java.lang.Object")}
		//parametize((new Date()).toString(),",","java.lang.Object");
		Date a=new Date();
 
		Date b=new Date();
 
		String rawString=param((Date)b, Date.class.toString() );					
		//System.out.println(rawString);
 
		//Replaced=#{t:call("Gregs ' car", 'java.lang.String', 'replace', t:params( parameter ))}
 
		String paramA=param("\\u0027","");
		String paramB=param("\\u0022","");
		String params=paramA+paramB;
		String in="I need to ' have a replaced single quote with double";
		String out=(String)call(in, "java.lang.String", "replace", params(params));
 
		System.out.println(out);
 
 
		/*
		Object[] obj=params(rawString);
		for(Object o:obj){
			System.out.println(o);
		}
		//c(call(null, "@DateUtil", "normalizeDate", obj));
 
		*/
 
	}
 
}

I hope this helps, btw this was copied/pasted from my project so not sure if I missed anything.

Project quitsomething.com rolled out

Just started working on a new project quitsomething.com, idea is simple keeps a diary of things that I want to quit hence the name “quitsomething”.

Technology

  • C#
  • jQuery
  • NHibernate with MySQL
  • Twitter Integration

Why NHibernate with MySQL? Well I am familiar with Hibernate and MySQL and I don’t want to pay extra for having extra MSSql Database from my hosting provider.

Update

Project have officially moved to public beta, I am having a designer taking a look at the site design and making some improvements.

Official launch is for Jan 01 2010, just in time to create your New Year resolutions.

Xpath alternate row colors

This XPath expression will let you alternate row colors

Alternate Rows
<wr:if select="1+count(preceding-sibling::*)  mod 2 = 1">
	ROW A Color
<wr:else/>
	ROW B Color
</wr:if>

Example

I will provide complete example soon.

Scrolling div on Android in webview

Problem

Simple thing as scrolling a div with overflow:auto is currently not possible on the Android platform.
Due to my application requirement I really needed this functionality so here is what I come up with

Challenges

Currently when we call node.offsetHeight we will not get the full height of the div only the content visible
to fix that I change the positioning to absolute and height 100% to get the true height of the div.

Android project with scrollable div can be download here

Code

Code consist of three parts

  • CSS
  • JavaScript
  • HTML markup
.scroller_container{
  	position:relative;  border:1px solid #CCC; overflow:hidden; top:0;left:0
  }
  .scroller{
  	position:relative; float:left; 
  }
 
  .scroller_navigator{
  	float:right;border:1px solid #CCC; height:150px; width:45px;
  }
 
  .scroll_down, .scroll_up{
  	clear:left;padding:8px
  }
 
  .scroller_navigator_spacer{
  	width:10px; height:48px; clear:left;
  }
 /**
		 * WebKit Div Scroller class
		 * @author:Greg Bugaj
		 * Initial release
		 */
		 //Namespace
		var GB=GB || {};
		GB.Scroller=
		{
			SCROLL_INREMENT:5,//Amount to scroll per update
			SCROLL_TIME:75,//Time between update Intervals in  MS	
 
			getElementsByClassName:function(classname, node)  {
				if (!node) {
					node = document.getElementsByTagName('BODY')[0];
				}
				var a = [];
				var re = new RegExp('\\b' + classname + '\\b');
				var els = node.getElementsByTagName("*");
				for(var i=0,j=els.length; i<j; i++){
					if(re.test(els[i].className))a.push(els[i]);
				}				
			    return a;
			},
			//Attached event to the scrollable components
			init:function(){
				var root = document.getElementsByTagName('BODY')[0];
				var containers=GB.Scroller.getElementsByClassName("scroller_container", root);
 
				for(var i=0;i<containers.length;i++){
					var scroller_container = containers[i];
					//Copy old properties
					var old={
						position:scroller_container.style.position, 
						height:scroller_container.style.height, 
						overflow:scroller_container.style.overflow
					};
 
					//Set new props*/
					scroller_container.style.position="absolute";
					scroller_container.style.height="100%";
					scroller_container.style.overflow="none";
 
					var scroller = GB.Scroller.getElementsByClassName("scroller", scroller_container);
						if(scroller==null){
							alert("There is no DIV with class 'scroller'");
						}
						scroller=scroller[0];//There should be only 1 element in the array
 
					var contentHeight = scroller.offsetHeight;   
 
					//Move the element back to it original positon with its original values
					scroller_container.style.position=old.position;
					scroller_container.style.height=old.height;
					scroller_container.style.overflow=old.overflow;
 
					var visibleContentHeight = scroller_container.offsetHeight ;
					var iTimer=0;
						/**
						 * Scroll content layer up/down
						 * @param {Object} e
						 * @param {Object} direction to scroll
						 */
					var scrollContent=function(e, direction){
						var t=parseInt(scroller.style.top);
						var cancelTimer=false;
						/*Scroll text up*/
						if(direction == -1 && ((contentHeight+scroller.offsetTop) < visibleContentHeight)){
							cancelTimer=true;
						}/*Scroll text down*/
						else if(direction == 1/*DOWN*/ && ((contentHeight+scroller.offsetTop) >=  contentHeight)){
							cancelTimer=true;
						}
						if(cancelTimer){
							clearInterval(iTimer);
							return;
						}						
						t+=GB.Scroller.SCROLL_INREMENT*direction;
						scroller.style.top=t+"px";				
					};
 
 
					//Attach events to navigation 
					var tapUP = GB.Scroller.getElementsByClassName("scroll_up", scroller_container);
					if(tapUP==null){
						alert("There is no DIV with class 'scroll_up'");
					}
					tapUP=tapUP[0];//There should be only 1 element in the array
 
					var tapDOWN = GB.Scroller.getElementsByClassName("scroll_down", scroller_container);
					if(tapDOWN==null){
						alert("There is no DIV with class 'scroll_down'");
					}
					tapDOWN=tapDOWN[0];//There should be only 1 element in the array
 
 
					tapUP.addEventListener('touchstart', function(e){
						iTimer=setInterval(function(){ scrollContent(e, -1);}, GB.Scroller.SCROLL_TIME);
					}, false);
 
					tapUP.addEventListener('touchend', function(e){
						clearInterval(iTimer);
					}, false);
 
					tapDOWN.addEventListener('touchstart', function(e){
							iTimer=setInterval(function(){scrollContent(e, 1);}, GB.Scroller.SCROLL_TIME);
					}, false);
 
					tapDOWN.addEventListener('touchend', function(e){
						clearInterval(iTimer);
					}, false);
 
				}//for
			}//function
		};
 
		//Initialize all the scrollable components on the page
		window.addEventListener('load', function(){ GB.Scroller.init(); }, true);
   <div class="scroller_container" style="width:318px; height:150px;">
        <div class="scroller" style="width:205px; top:0;left:0;"> 
            Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec dapibus ipsum in nulla rhoncus a blandit enim lobortis. Mauris scelerisque justo eu purus molestie ut sodales diam laoreet. Integer id volutpat urna. Sed lacinia risus id magna pharetra scelerisque. Proin venenatis blandit sapien vitae pulvinar. Nulla et urna in erat venenatis posuere eu id ipsum. Proin magna mi, congue ultrices malesuada id, sollicitudin a urna. Praesent id lorem leo. Phasellus vestibulum dapibus mattis. Fusce et faucibus risus.  
     Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec dapibus ipsum in nulla rhoncus a blandit enim lobortis. Mauris scelerisque justo eu purus molestie ut sodales diam laoreet. Integer id volutpat urna. Sed lacinia risus id magna pharetra scelerisque. Proin venenatis blandit sapien vitae pulvinar. Nulla et urna in erat venenatis posuere eu id ipsum. Proin magna mi, congue ultrices malesuada id, sollicitudin a urna. Praesent id lorem leo. Phasellus vestibulum dapibus mattis. Fusce et faucibus risus.     </div><!--//scroller-->
 
	<div class="scroller_navigator"><!-- Navigation -->
		<div class="scroll_down" >
			<img src="arrow_up.png" width="32" height="32" alt="Scroll content down" / >
		</div>
		<!-- Spacer between scroll icons  -->
		<div class="scroller_navigator_spacer"> </div>
 
		<div class="scroll_up">
			<img src="arrow_down.png" width="32" height="32" alt="Scroll content up" />
		</div>
	</div>  
 
    </div><!--//scroller_container-->

Feature request/updates

I will add features as I need them or upon request.

Android ImpulseShopper released

About

ImpulseShopper(pre-beta) is application that lets you monitor your favorite daily deals websites like woot.com, 1saleaday.com, dailysteals.com etc…
Includes both widget and full blown application.

  • Engine based
  • Filters
  • Product thumbnails
  • Share via SMS, Email, Twitter
  • Notifications
  • Deployed on Google AppEngine

Screenshots

HashTable implemented using quadratic probing for collision resolution

Using quadratic probing for collision resolution

#define ERROR_TABLE_FULL       -1
#define ERROR_RECORD_NOT_FOUND -1
#define ERROR_DUPLICATE_RECORD -1
 
class HashTable{
public:
	HashTable(int table_size);
	int insert(const string &record);
	int retrieve(const string &record);
private:
	int hash(const string &record);
	int hash_size;
	int record_count;
	string* table;
};
 
/**
 * Constructor accepting table_size
 */
HashTable::HashTable(int table_size){
	hash_size = table_size;
	table = new string[hash_size];
	record_count = 0;
}
/**
 * Hash function calculated using
 * product p of all the characters of the key
 * and then returns the index where index=s%hash_size
 */
int HashTable::hash(const string &key) {
	int value = 1;
	for (int position = 0; position < max_key_length; position++){
		if(key[position] == 0){
			break;
		}
		value *= key[position];
	}
	value %= hash_size;
	if (value < 0){
		value += hash_size;
	}
	return value;
}
/**
 * Insert new record
 * Collision function uses h+i^2
 *
 */
int HashTable::insert(const string &record){
	if(record_count == hash_size){
		return ERROR_TABLE_FULL;
	}
 
	int hash_key = hash(record);
	int increment = 1;
 
	int probe_counter=0;
	int hash_mid=(hash_size+1)/2;
 
	while(1){
		//Check for overflow
		if(probe_counter > hash_mid){
			return ERROR_RECORD_NOT_FOUND;
		}
		string tmp = table[hash_key];
		//Empty slot
		if(tmp.empty()){
			break;
		}//Position already taken, duplicate keys are not allowed
		else if(tmp.compare(record) == 0) {
			return ERROR_DUPLICATE_RECORD;
		}
		else{
			//Handles collision using h+i^2
			hash_key = (hash_key+increment) % hash_size;
			increment+=2;
			probe_counter++;
		}
	}
	table[hash_key] = record;
	record_count++;
	return hash_key;
 
}
/**
 * Retrieve record index
 */
int HashTable::retrieve(const string &record){
	int hash_key = hash(record);
	int increment = 1;
 
	int probe_counter=0;
	int hash_mid=(hash_size+1)/2;
 
	while(1){
		//Overflow encountered if the probe is bigger than hash_size/2
		if(probe_counter > hash_mid){
			return ERROR_RECORD_NOT_FOUND;
		}
		string tmp = table[hash_key];
		//Record empty for the key
		if(tmp.empty()) {
			break;
		}
		else if(tmp.compare(record) == 0){
			return hash_key;
		}
		else{
			hash_key = (hash_key+increment) % hash_size;
			increment+=2;
			probe_counter++;
		}
	}
	return ERROR_RECORD_NOT_FOUND;
}

HashTable implemented using linear probing for collision resolution

Using linear probing for collision resolution in hashtable

 
#define ERROR_TABLE_FULL       -1
#define ERROR_RECORD_NOT_FOUND -1
#define ERROR_DUPLICATE_RECORD -1
 
class HashTable{
public:
	HashTable(int table_size);
	int insert(const string &record);
	int retrieve(const string &record);
 
private:
	int hash(const string &record);
	int hash_size;
	int record_count;
	string* table;
};
 
/**
 * Constructor accepting table_size
 */
HashTable::HashTable(int table_size){
	hash_size = table_size;
	table = new string[hash_size];
	record_count = 0;
}
 
/**
 * Hash function calculated using
 * product p of all the characters of the key
 * and then returns the index where index=s%hash_size
 */
int HashTable::hash(const string &record) {
	int value = 1;
	for (int position = 0; position < max_key_length; position++){
		if(record[position] == 0){
			break;
		}
		value *= record[position];
	}
	value %= hash_size;
	if (value < 0){
		value += hash_size;
	}
	return value;
}
 
/**
 * Insert new record into out table, making sure that the table is not full
 */
int HashTable::insert(const string &record){
	//Check if HashTable is full if it is then return overflow
	if(record_count == hash_size){
		return ERROR_TABLE_FULL;
	}
	int hash_key = hash(record);
	while(1){
		string tmp = table[hash_key];
		//Check if table bucket is empty
		if(tmp.empty()) {
			break;
		}//Position already taken, duplicate keys are not allowed 0 = equal
		else if(tmp.compare(record) == 0) {
			return ERROR_DUPLICATE_RECORD;
		}
		//Collision detected multiple records mapped to same location
		//Try next bucket
		else {
			hash_key = (hash_key+1) % hash_size;
		}
	}
	table[hash_key] = record;
	record_count++;
 
	return hash_key;
}
 
/**
 * Retrieve record index
 */
int HashTable::retrieve(const string &record){
	int hash_key = hash(record);
	while(1){
		string tmp = table[hash_key];
		//Record empty for the key
		if(tmp.empty()){
			break;
		}//if entry found return index
		else if(tmp.compare(record) == 0) {
			return hash_key;
		}
		else { //Resolving collision using linear probing
			hash_key = (hash_key+1) % hash_size;
		}
	}
 
	//No record Found
	return ERROR_RECORD_NOT_FOUND;
}

Quicksort implementation using Linked List

About QuickSort

Wikipedia QuickSort definition.

General idea revolves around partitioning a list where values less than pivot go into left list while greater than go into right list.
Pivot here is the first item of the passed in list. We apply this recursively to the sublists them merge left+pivot+right.

CPP Code

First of all not a cpp developer so if you can improve this them post a comment with suggestions.

 
template <class Record>
Node<Record> * List<Record>::quick_sort_recursive(Node<Record>* list)
{
	//Base case : list  is NULL
	if(list ==  NULL){
		return NULL;
	}
 
	//We choose first entry in the list as the pivot node
	Node<Record> * pivotNode = new Node<Record>();
	pivotNode->entry=list->entry;
	Record pivot = pivotNode->entry;
 
	Node<Record> *tmp=list->next;
	Node<Record> *leftHead=NULL;
	Node<Record> *rightHead=NULL;
 
	Node<Record> *leftTail=NULL;
	Node<Record> *rightTail=NULL;
 
	//Partition the list into left/right sublists
	while(tmp != NULL){
		Node<Record> *entryNode=new Node<Record>();
		entryNode->entry = tmp->entry;
		entryNode->next = NULL;
		if(tmp->entry < pivot){
			if(leftTail == NULL){
				leftTail = entryNode;
				leftHead=entryNode;
			}else{
				leftTail->next=entryNode;
				leftTail=leftTail->next;
			}
		}
		else{
			if(rightTail == NULL){
				rightTail = entryNode;
				rightHead=entryNode;
			}else{
				rightTail->next=entryNode;
				rightTail=rightTail->next;
			}
		}
		tmp = tmp->next;
	}
 
	//Recursively subdivide the left / right list
	leftHead  = quick_sort_recursive(leftHead);
	rightHead = quick_sort_recursive(rightHead);
 
	//Combine left+pivot+right
	Node<Record> * mergedHead=NULL;
	Node<Record> * mergedTail=NULL;
 
	Node<Record> *tmpNode=leftHead;
	while(tmpNode){
		Node<Record> *new_node=new Node<Record>();
		new_node->entry=tmpNode->entry;
		if(mergedTail == NULL){
			mergedTail = new_node;
			mergedHead= new_node;
		}else{
			mergedTail->next= new_node;
			mergedTail=mergedTail->next;
		}
		tmpNode=tmpNode->next;
	}
	//Pivot point
	if(mergedTail == NULL){
		mergedTail = pivotNode;
		mergedHead = pivotNode;
	}else{
		mergedTail->next=pivotNode;
		mergedTail=mergedTail->next;
	}
	//Right sublist
	tmpNode=rightHead;
	while(tmpNode){
		Node<Record> *new_node=new Node<Record>();
		new_node->entry=tmpNode->entry;
		mergedTail->next=new_node;
		mergedTail=mergedTail->next;
		tmpNode=tmpNode->next;
	}
 
	return mergedHead;
}
 
 
 
template <class Node_entry>
struct Node {
//  data members
   Node_entry entry;
   Node<Node_entry> *next;
//  constructors
   Node();
   Node(Node_entry, Node<Node_entry> *link = NULL);
};

Sidebar3 : Please add some widgets here.