001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * *** 008 * 009 * Community License: GPL 3.0 010 * 011 * This file is free software: you can redistribute it and/or modify 012 * it under the terms of the GNU General Public License as published 013 * by the Free Software Foundation, either version 3 of the License, 014 * or (at your option) any later version. 015 * 016 * This file is distributed in the hope that it will be useful, but 017 * WITHOUT ANY WARRANTY; without even the implied warranty of 018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 019 * GNU General Public License for more details. 020 * 021 * You should have received a copy of the GNU General Public License 022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 023 * 024 * *** 025 * 026 * Available Commercial License: GraniteDS SLA 1.0 027 * 028 * This is the appropriate option if you are creating proprietary 029 * applications and you are not prepared to distribute and share the 030 * source code of your application under the GPL v3 license. 031 * 032 * Please visit http://www.granitedataservices.com/license for more 033 * details. 034 */ 035package org.granite.client.tide.data.impl; 036 037import java.util.ArrayList; 038import java.util.List; 039import java.util.WeakHashMap; 040 041import org.granite.client.tide.data.spi.DataManager; 042 043/** 044 * Implementation of HashSet that holds weak references to UID entities 045 * 046 * @author William DRAI 047 */ 048public class UIDWeakSet { 049 050 private final DataManager dataManager; 051 private final WeakHashMap<Object, Object>[] table; 052 053 054 public UIDWeakSet(DataManager dataManager) { 055 this(dataManager, 64); 056 } 057 058 @SuppressWarnings("unchecked") 059 public UIDWeakSet(DataManager dataManager, int capacity) { 060 this.dataManager = dataManager; 061 table = new WeakHashMap[capacity]; 062 } 063 064 public void clear() { 065 for (int i = 0; i < table.length; i++) 066 table[i] = null; 067 } 068 069 public Object put(Object uidObject) { 070 int h = hash(dataManager.getCacheKey(uidObject)); 071 072 WeakHashMap<Object, Object> dic = table[h]; 073 if (dic == null) { 074 dic = new WeakHashMap<Object, Object>(); 075 table[h] = dic; 076 } 077 078 Object old = null; 079 for (Object o : dic.keySet()) { 080 if (o == uidObject) 081 return o; 082 083 if (dataManager.getUid(o) == dataManager.getUid(uidObject) && o.getClass().getName().equals(uidObject.getClass().getName())) { 084 old = o; 085 dic.remove(o); 086 break; 087 } 088 } 089 090 dic.put(uidObject, null); 091 092 return old; 093 } 094 095 public Object get(String cacheKey) { 096 int h = hash(cacheKey); 097 098 Object uidObject = null; 099 100 WeakHashMap<Object, Object> dic = table[h]; 101 if (dic != null) { 102 for (Object o : dic.keySet()) { 103 if (dataManager.getCacheKey(o).equals(cacheKey)) { 104 uidObject = o; 105 break; 106 } 107 } 108 } 109 110 return uidObject; 111 } 112 113 public static interface Matcher { 114 115 public boolean match(Object o); 116 } 117 118 public Object find(Matcher matcher) { 119 for (int i = 0; i < table.length; i++) { 120 WeakHashMap<Object, Object> dic = table[i]; 121 if (dic != null) { 122 for (Object o : dic.keySet()) { 123 if (matcher.match(o)) 124 return o; 125 } 126 } 127 } 128 return null; 129 } 130 131 public static interface Operation { 132 133 public void apply(Object o); 134 } 135 136 public void apply(Operation operation) { 137 for (int i = 0; i < table.length; i++) { 138 WeakHashMap<Object, Object> dic = table[i]; 139 if (dic != null) { 140 for (Object o : dic.keySet()) 141 operation.apply(o); 142 } 143 } 144 } 145 146 public Object remove(String cacheKey) { 147 int h = hash(cacheKey); 148 149 Object uidObject = null; 150 151 WeakHashMap<Object, Object> dic = table[h]; 152 if (dic != null) { 153 for (Object o : dic.keySet()) { 154 if (dataManager.getCacheKey(o).equals(cacheKey)) { 155 uidObject = o; 156 dic.remove(o); 157 break; 158 } 159 } 160 } 161 162 return uidObject; 163 } 164 165 public int size() { 166 int size = 0; 167 168 for (int i = 0; i < table.length; i++) { 169 WeakHashMap<Object, Object> dic = table[i]; 170 if (dic != null) 171 size += dic.size(); 172 } 173 174 return size; 175 } 176 177 public List<Object> data() { 178 List<Object> d = new ArrayList<Object>(); 179 180 for (int i = 0; i < table.length; i++) { 181 WeakHashMap<Object, Object> dic = table[i]; 182 if (dic != null) 183 d.addAll(dic.keySet()); 184 } 185 return d; 186 } 187 188 private int hash(String uid) { 189 int h = 0; 190 int max = uid.length(); 191 for (int i = 0; i < max; i++) 192 h = (31 * h) + uid.charAt(i); 193 return (Math.abs(h) % table.length); 194 } 195}