Quadcap Embeddable Database

com/quadcap/util/collections/LongMap.java

Go to the documentation of this file.
00001 package com.quadcap.util.collections; 00002 00003 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved. 00004 * 00005 * This software is distributed under the Quadcap Free Software License. 00006 * This software may be used or modified for any purpose, personal or 00007 * commercial. Open Source redistributions are permitted. Commercial 00008 * redistribution of larger works derived from, or works which bundle 00009 * this software requires a "Commercial Redistribution License"; see 00010 * http://www.quadcap.com/purchase. 00011 * 00012 * Redistributions qualify as "Open Source" under one of the following terms: 00013 * 00014 * Redistributions are made at no charge beyond the reasonable cost of 00015 * materials and delivery. 00016 * 00017 * Redistributions are accompanied by a copy of the Source Code or by an 00018 * irrevocable offer to provide a copy of the Source Code for up to three 00019 * years at the cost of materials and delivery. Such redistributions 00020 * must allow further use, modification, and redistribution of the Source 00021 * Code under substantially the same terms as this license. 00022 * 00023 * Redistributions of source code must retain the copyright notices as they 00024 * appear in each source code file, these license terms, and the 00025 * disclaimer/limitation of liability set forth as paragraph 6 below. 00026 * 00027 * Redistributions in binary form must reproduce this Copyright Notice, 00028 * these license terms, and the disclaimer/limitation of liability set 00029 * forth as paragraph 6 below, in the documentation and/or other materials 00030 * provided with the distribution. 00031 * 00032 * The Software is provided on an "AS IS" basis. No warranty is 00033 * provided that the Software is free of defects, or fit for a 00034 * particular purpose. 00035 * 00036 * Limitation of Liability. Quadcap Software shall not be liable 00037 * for any damages suffered by the Licensee or any third party resulting 00038 * from use of the Software. 00039 */ 00040 00041 import java.util.Iterator; 00042 00043 import com.quadcap.util.Debug; 00044 00045 /** 00046 * A map with long values as keys 00047 * 00048 * @author Stan Bailes 00049 */ 00050 public class LongMap { 00051 int size = 0; 00052 Entry[] entries; 00053 Entry freeList; 00054 00055 /** 00056 * Create an empty map with a specified number of buckets. 00057 */ 00058 public LongMap(int initSize) { 00059 initSize |= 1; 00060 while (!isPrime(initSize)) initSize += 2; 00061 entries = new Entry[initSize]; 00062 } 00063 00064 /** 00065 * Return the Object with the specified key value 00066 */ 00067 public synchronized final Object get(long key) { 00068 int h = hash(key); 00069 for (Entry entry = entries[h]; entry != null; entry = entry.next) { 00070 if (entry.key == key) return entry.val; 00071 } 00072 return null; 00073 } 00074 00075 /** 00076 * Insert a key, value pair 00077 */ 00078 public synchronized final void put(long key, Object val) { 00079 int h = hash(key); 00080 for (Entry entry = entries[h]; entry != null; entry = entry.next) { 00081 if (entry.key == key) { 00082 entry.val = val; 00083 return; 00084 } 00085 } 00086 Entry entry = getEntry(key, val); 00087 entry.next = entries[h]; 00088 entries[h] = entry; 00089 } 00090 00091 /** 00092 * Remove the specified key 00093 */ 00094 public synchronized final void remove(long key) { 00095 int h = hash(key); 00096 Entry prev = null; 00097 Entry entry = entries[h]; 00098 while (entry != null) { 00099 Entry next = entry.next; 00100 if (entry.key == key) { 00101 if (prev == null) { 00102 entries[h] = next; 00103 } else { 00104 prev.next = next; 00105 } 00106 freeEntry(entry); 00107 return; 00108 } 00109 prev = entry; 00110 entry = next; 00111 } 00112 } 00113 00114 public String toString() { 00115 StringBuffer sb = new StringBuffer("{"); 00116 LongIterator k = keys(); 00117 String delim = ""; 00118 while (k.hasNext()) { 00119 long v = k.nextLong(); 00120 Object d = get(v); 00121 sb.append(delim); 00122 sb.append(v); 00123 sb.append('='); 00124 sb.append(String.valueOf(d)); 00125 delim = ","; 00126 } 00127 sb.append("}"); 00128 return sb.toString(); 00129 } 00130 00131 00132 00133 /** 00134 * Return the number of entries 00135 */ 00136 public final int size() { return size; } 00137 00138 public final int buckets() { return entries.length; } 00139 00140 //------------------------------------------------------- 00141 final Entry getEntry(long key, Object val) { 00142 Entry entry = freeList; 00143 if (entry == null) { 00144 entry = new Entry(); 00145 } else { 00146 freeList = entry.next; 00147 } 00148 entry.key = key; 00149 entry.val = val; 00150 size++; 00151 return entry; 00152 } 00153 00154 final void freeEntry(Entry entry) { 00155 size--; 00156 entry.val = null; 00157 entry.next = freeList; 00158 freeList = entry; 00159 } 00160 00161 final boolean isPrime(int x) { 00162 return IntMap.isPrime(x); 00163 } 00164 00165 public LongIterator keys() { 00166 return new LongMapIterator(this); 00167 } 00168 00169 final int hash(long key) { 00170 int h = (int)(key % entries.length); 00171 if (h < 0) { 00172 h = 0 - h; 00173 } 00174 return h; 00175 } 00176 00177 class Entry { 00178 long key; 00179 Object val; 00180 Entry next; 00181 } 00182 00183 public class LongMapIterator implements LongIterator { 00184 LongMap map; 00185 int epos = 0; 00186 Entry entry = null; 00187 Entry last = null; 00188 00189 public LongMapIterator(LongMap map) { 00190 this.map = map; 00191 advance(); 00192 } 00193 00194 public boolean hasNext() { 00195 return entry != null; 00196 } 00197 00198 void advance() { 00199 last = entry; 00200 if (entry != null && entry.next != null) { 00201 entry = entry.next; 00202 } else { 00203 entry = null; 00204 } 00205 while (epos < map.entries.length && entry == null) { 00206 entry = map.entries[epos++]; 00207 } 00208 } 00209 00210 public Object next() { 00211 Long ret = null; 00212 if (entry != null) { 00213 ret = new Long(entry.key); 00214 advance(); 00215 } 00216 return ret; 00217 } 00218 00219 public long nextLong() { 00220 long ret = 0; 00221 if (entry != null) { 00222 ret = entry.key; 00223 advance(); 00224 } 00225 return ret; 00226 } 00227 00228 public void remove() { 00229 if (last != null) { 00230 map.remove(last.key); 00231 last = null; 00232 } 00233 } 00234 } 00235 }