Virtual Machinery logoBTree logo
  BTree Session Bean Demo
BTree Home Download code Deployment Guide Using a different BTree Redeploy after changes Security

It seems that BTrees are percieved as a forgotten technology, relegated to computing courses as an interesting aside. They have been widely used as the underlying data storage mechanism in relational databases and are found in operating environments such as Novell and languages such as MUMPS. Fashion and the wider choice of database solutions may apparently have passed them by but they are still a powerful tool in the professional programmers armoury - they have a significant role in the Application Server space as this demo will show.

Full code for this demonstration is available by clicking on the 'Download code' link in the title bar above. This will allow you to create a working example of the principles outlined here based on Virtual Machinerys BTree technology. This code is released under the terms of the license which you can find here .

You can find out more about our BTree implementation on the BTree FAQ page. We also have some BTree programming tips and tricks listed here which will show you how to make the most efficient use of BTrees in your application. We always welcome feedback on our product and demos - please feel free to contact us using the link at the bottom of the page.

In terms of their design and functional attributes BTrees lie somewhere between Hashmaps and databases. The features are summarised in the following table.


HashMap BTree Database
Access Fast Slow (but fast when cached) Slow (but fast when cached)
Ultimate Storage Memory Disk Disk
Object Handling Can handle objects in their entirety Objects must be Strings or be capable of being streamed Objects must be matched to database tables
Management Overhead Low Low High
Data Location All data must be in memory Data can be in memory or on disk Data can be in memory or in table

Note that you can implement a BTree entirely in memory without having files to persist it. We don’t cover this situation here.

Ideal Situations for using BTrees in a J2EE environment

  • Where you have more data than can be comfortably accommodated in a Java Hashmap
  • Where there is a large amount of data but rapid and frequent access is required to only a small subset of that data. For example you might have 5 million accounts but only twenty thousand of them are active. By using the BTree caching mechanism provided by Virtual Machinery the most frequently used data will always be in memory rather than on disk.
  • Where the data is simple and has a string index e.g. Error codes, message translation tables, or where you simply want to check its existence e.g. valid bank sort codes
  • Where the data is not updated frequently e.g. changing on a nightly basis
In terms of efficiency when using a cached BTree the ideal situation is to cache the entire index set (this is usually quite small) – this means that each lookup will require at most one disk access. This situation can improve dramatically where a small subset of the data will satisfy the vast majority of the requests – e.g. a bank in Ireland will spend most of its time validating Irish sort codes but will need to have other sort codes available. In this case you only need to cache a fraction of the data set – by doing this you will speed up the majority of enquiries while still giving access to all of the data in the time it takes to do a single disk lookup. The greater an understanding of your data that you have the more efficient you will be able to make your lookups.

Using the EJB model with a BTree

We have decided to use the Single Stateless Session Bean pattern proposed by Kyle Brown in the Websphere Technical Journal (see the section headed Does your application contain a relatively small set of objects that are very rarely, or never updated, but whose state is frequently read? ).As well as replacing the database with a BTree we’ve made some modifications to this pattern – notably not using a broker – for simplification. Note that in a real world scenario you have to consider how you refresh the data in a production (particularly a 24/7) environment.

Our implementation of this pattern creates and ensures a single instance of each BTree. A standard Java class is used to manage the single instance and the SSB uses this instance to satisfy the data requests that it receives. The access method on the Accounts class has been synchronised to ensure that multiple users can safely access the BTree (Virtual Machinery’s BTree implementation is not thread safe and must be protected by a synchronized method if used in a multi-thread environment– You can easily create a synchronized version of the BTree implementation by subclassing if you prefer).

The SSB is then responsible simply for getting the data from the BTree. The code for the SSB will look something like this –

import java.rmi.RemoteException; 
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;

public class BTreeDemoBean implements SessionBean {

    public String getDetails(String anAccount) {
	String answer = Accounts.getInstance().get(anAccount);
        return answer;
    }

    public BTreeDemoBean() {}
    public void ejbCreate() {}
    public void ejbRemove() {}
    public void ejbActivate() {}
    public void ejbPassivate() {}
    public void setSessionContext(SessionContext sc) {}
}

And the code for the POJO (Plain old Java object) that handles the BTree will look like this –

import com.virtualmachinery.btreero.btree.BTreeRO;
import com.virtualmachinery.btree.exceptions.*;

public class Accounts {
  private static Accounts accountsInstance;
  private BTreeRO aBTree;

  private Accounts(BTreeRO aTree) {
    aBTree = aTree;
    try { aBTree.loadMem();  }
    catch (BTreeException anException) { anException.printStackTrace(); }      
  }

  public static synchronized  Accounts getInstance() {
    if (accountsInstance == null) {
      try {
	System.out.println("Opening BTree");
        accountsInstance = new Accounts(new BTreeRO( "C:\\VMPHONETEST.DAT","C:\\VMPHONETEST.IND",3,132));
	System.out.println("Successfully Opened BTree");
       }
       catch (Exception anException) { System.out.println(anException); }
    }   
    return accountsInstance;
  }

  public synchronized String get(java.lang.String accountNumber) {
    try { return aBTree.get(accountNumber);  }
    catch (BTreeException anException) { anException.printStackTrace(); }
    return null;
  }
}

You will also need a Home and a Remote interface. For the sake of completeness the code is included below –

//Home Interface 
import java.io.Serializable;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;

public interface BTreeDemoHome extends EJBHome {
    BTreeDemo create() throws RemoteException, CreateException;
}

//Remote Interface
import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface BTreeDemo extends EJBObject {
    public String getDetails(String anAccount) throws RemoteException;
}

Creating a Web Client

Now all we have left is the presentation logic - we can use a relatively trivial jsp -

<%@ page import="btreedemo.BTreeDemo, btreedemo.BTreeDemoHome, javax.ejb.*, java.math.*, javax.naming.*, javax.rmi.PortableRemoteObject, java.rmi.RemoteException" %>
<%!
   private BTreeDemo demo = null;

   public void jspInit() { 
      try {
         InitialContext ic = new InitialContext();
         Object objRef = ic.lookup("java:comp/env/ejb/BTreeDemo");
         BTreeDemoHome home = (BTreeDemoHome)PortableRemoteObject.narrow(objRef, BTreeDemoHome.class);
         demo = home.create();
      } catch (RemoteException ex) {
            System.out.println("Couldn't create demo bean."+ ex.getMessage());
      } catch (CreateException ex) {
            System.out.println("Couldn't create demo bean."+ ex.getMessage());
      } catch (NamingException ex) {
            System.out.println("Unable to lookup home: "+ "BTreeDemo "+ ex.getMessage());
      } 
   }

   public void jspDestroy() {    
         demo = null;
   }
%>
<html>
<head>
    <title>Account Lookup</title>
</head>

<body bgcolor="white">
<h1><b><center>Account Lookup</center></b></h1>
<hr>
<p><b>Enter an account number to show details:</p>
<form method="get">
<input type="text" name="account" size="25">
<br>
<p>
<input type="submit" value="Get Details">
</form>

<%
    String account = request.getParameter("account");
    if ( account != null && account.length() > 0 ) {
%>
   <p>
   Details for Account <%= account %> are  <%= demo.getDetails(account) %>.
<%
    }
%>

</body>
</html>

Deploying the code

The code above should be deployable on any J2EE compliant application server. All of the code required is in the ..\code\btreedemo\src directory of your installation and the .jsp file can be found in the ..\code\btreedemo\web directory. Specific details on how to deploy the code in the Sun J2EE reference environment can be found here. These instructions may also be useful for deployment in other environments. Thios page also includes details on how to change the code to use different BTrees and different BTree locations and some information on security problems that may arise when building and deploying the aplication.

A Quick guide to BTrees gives an overview of the underlying principles of BTrees. You can also find details about Virtual Machinery's BTree implementation here. You can see license pricing and buy Virtual Machinerys BTree implementation online - just click on the button to the right.

You may also be interested in our free guide to Java Metrics which is available here .

You may be interested in some of our other products. All have demo or trial versions. Just click on the links below to find out more -


 
 
 

Contact Us

All Content © 2013 Virtual Machinery   All Rights Reserved.