<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title><![CDATA[Latest posts for the topic "Indexing"]]></title>
		<link>http://s4j.mentaframework.org/posts/list/2.page</link>
		<description><![CDATA[Latest messages posted in the topic "Indexing"]]></description>
		<generator>JForum - http://www.jforum.net</generator>
			<item>
				<title>Indexing</title>
				<description><![CDATA[ When your collection becomes too big, even in-memory searches can become expensive. Imagine a Java collection with 1 million users and you need to find all users with the last name equals to "Smith". Iterating through all elements is clearly not an option. What you need is INDEXES.<br /> <br /> Space4J supports 4 different types of indexes through maps, in other words, when you create an index a new Java Map is created to store the index.<br /> <br /> The four types of index are:<br /> <br /> :arrow: Index.TYPE.REGULAR = Unique index non-sorted. This is used to get an user by its id for example, where each user has an unique id.<br /> [code]<br /> User u = usersById.get(2345);<br /> [/code]<br /> <br /> :arrow: Index.TYPE.SORTED = Unique index sorted. This is used to get a list of users in a range of ids (ex: 4000 &lt; id &lt; 5000). Also used when you need to fetch users sorted by the indexed field.<br /> [code]<br /> Map&lt;Integer, User&gt; map = usersById.subMap(4000, 5000);<br /> [/code]<br /> <br /> :arrow: Index.TYPE.MULTI = Non-unique index non-sorted. This is used to get all users with age equal to 23.<br /> [code]<br /> Collection&lt;Object&gt; coll = (Collection&lt;Object&gt;) usersByAge.get(23);<br /> [/code]<br /> <br /> :arrow: Index.TYPE.MULT_SORTED = Non-unique index sorted. This is used to get all users with age &gt;= 23 and age &lt;= 40. Also used when you need to fech users sorted by the indexed field.<br /> [code]<br /> Map&lt;Integer, Collection&lt;User&gt;&gt; map = usersByAge.subMap(23, 40);<br /> [/code]<br /> <br /> The [url="http://www.space4j.org/phonebookindex.jsp"]PhoneBookIndexing.java[/url] program provides examples of how to create and user indexes for your collections in memory. Below is the source code:<br /> [code]<br /> package org.space4j.examples.phonebook;<br /> <br /> <br /> import java.util.ArrayList;<br /> import java.util.Collection;<br /> import java.util.Iterator;<br /> import java.util.Map;<br /> import java.util.concurrent.ConcurrentNavigableMap;<br /> <br /> import org.space4j.Space4J;<br /> import org.space4j.implementation.SimpleSpace4J;<br /> import org.space4j.indexing.Index;<br /> import org.space4j.indexing.IndexManager;<br /> import org.space4j.indexing.Key;<br /> import org.space4j.indexing.MultiMap;<br /> import org.space4j.indexing.MultiSortedMap;<br /> <br /> public class PhoneBookIndexing extends PhoneBook {<br /> 	<br />     private static final String INDX_LASTNAME = "indx_lastname";<br />     <br />     private static final String INDX_AGE = "indx_age";<br /> 	<br />     private final Index indexByLastName;<br />     <br />     private final Index indexByAge;<br /> 	<br />     public PhoneBookIndexing(Space4J space4j) throws Exception {<br />     	<br />         super(space4j);<br />     	<br />         IndexManager im = space.getIndexManager();<br />     	<br />         // If index does not exist, let's create it...<br />         if (!im.checkIndex(INDX_LASTNAME)) {<br />             <br />             /*<br />              * Index name = INDX_LASTNAME<br />              * Map in the Space that will be indexed = MAP_NAME<br />              * Type of index = MULTI = non-unique index<br />              * Object that will be indexed = User.class<br />              * Atributes of the object that will be indexed = "lastName"<br />              * <br />              * We want to create this index because we will be searching<br />              * for Users by lastName. We don't want to do a full table<br />              * scan anymore like in the example without indexes.<br />              */<br />         	<br />             Index indx = new Index(INDX_LASTNAME, MAP_NAME, Index.TYPE.MULTI,<br />                     User.class, "lastName");<br />         	<br />             boolean ok = im.createIndex(indx, space4j);<br />             <br />             if (ok) {<br />             	<br />                 System.out.println(indx + " created!");<br />             	<br />             } else {<br />             	<br />                 System.out.println(indx + " could not be created!");<br />             }<br />         }<br />         <br />         // If index does not exist, let's create it...<br />         if (!im.checkIndex(INDX_AGE)) {<br />             <br />             /*<br />              * Index name = INDX_AGE<br />              * Map in the Space that will be indexed = MAP_NAME<br />              * Type of index = MULTI = non-unique sorted index<br />              * Object that will be indexed = User.class<br />              * Atributes of the object that will be indexed = "age"<br />              * <br />              * We want to create this index because we will be searching<br />              * for Users by age. The index will be SORTED because we want<br />              * to search for users in a age range. (age &gt; min and age &lt; max)<br />              */<br />          <br />             Index indx = new Index(INDX_AGE, MAP_NAME, Index.TYPE.MULTI_SORTED,<br />                     User.class, "age");<br />          <br />             boolean ok = im.createIndex(indx, space4j);<br />             <br />             if (ok) {<br />                <br />                 System.out.println(indx + " created!");<br />                <br />             } else {<br />                <br />                 System.out.println(indx + " could not be created!");<br />             }<br />         }<br /> <br />         <br />         indexByLastName = im.getIndex(INDX_LASTNAME);<br />         indexByAge = im.getIndex(INDX_AGE);<br />     }<br />     <br />     /*<br />      * Let's override our search method to use our<br />      * index instead of doing a full table scan.<br />      */<br />     @Override<br />     public Collection&lt;Object&gt; findUsers(String last) {<br /> 	<br />    	// Remember that our index is of the type MULTI.<br />    	// That's why we are doing this cast here.<br />     	<br />         MultiMap map = (MultiMap) indexByLastName.getMap();<br />         <br />         // A multi-map will store a Collection for each key.<br />         // That's why our index is NON-UNIQUE meaning the same<br />         // key can be associated with many entries in the map.<br />         // That makes sense as some users can have the same<br />         // last name.<br />     	<br />         Collection&lt;Object&gt; coll = (Collection&lt;Object&gt;) map.get(last);<br />     	<br />         return coll;<br />     }<br />     <br />     @Override<br />     public Collection&lt;Object&gt; findUsers(int minAge, int maxAge) {<br />        <br />        // Remember that our index is of the type MULTI_SORTED.<br />        // That's why we are doing this cast here.<br />        <br />        MultiSortedMap map = (MultiSortedMap) indexByAge.getMap();<br />        <br />        // A multi-sorted-map will store a Map for each key.<br />        // That's why our index is NON-UNIQUE meaning the same<br />        // key can be associated with many entries in the map.<br />        // The map is also sorted by its key, meaning we can<br />        // perform range searches efficiently.<br />        <br />        ConcurrentNavigableMap&lt;Key, Object&gt; subMap = map.subMap(new Key(minAge), true, new Key(maxAge), true);<br />        <br />        Collection&lt;Object&gt; users = new ArrayList&lt;Object&gt;(subMap.size() * 3);<br />        <br />        Iterator&lt;Object&gt; iter = subMap.values().iterator();<br />        <br />        while(iter.hasNext()) {<br />           <br />           // our collection here is actually a ConcurrentHashMap!<br />           <br />           Map&lt;Object, Boolean&gt; m = (Map&lt;Object, Boolean&gt;) iter.next();<br />           <br />           // this is not good as we are transversing the whole list twice!<br />           // TODO: Create custom iterator for MultiSortedMap to avoid this?<br />           <br />           Iterator&lt;Object&gt; iter2 = m.keySet().iterator();<br />           <br />           while(iter2.hasNext()) {<br />              <br />              users.add(iter2.next());<br />           }<br />        }<br />        <br />        return users;<br />     }<br />     <br />     public static void main(String[] args) throws Exception {<br />     	<br />         PhoneBookIndexing book = new PhoneBookIndexing(<br />                 new SimpleSpace4J("PhoneBook"));<br /> <br />         run(book);<br />     	<br />     }<br /> }<br /> [/code]<br /> ]]></description>
				<guid isPermaLink="true">http://s4j.mentaframework.org/posts/preList/5/5.page</guid>
				<link>http://s4j.mentaframework.org/posts/preList/5/5.page</link>
				<pubDate><![CDATA[Fri, 5 Sep 2008 16:13:04]]> GMT</pubDate>
				<author><![CDATA[ saoj]]></author>
			</item>
	</channel>
</rss>