comparison artifact-database/src/main/java/de/intevation/artifactdatabase/DatabaseCleaner.java @ 230:fbd57d2eeaef

Changed semantics of locked artifact ids. artifacts/trunk@1634 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 31 Mar 2011 14:48:28 +0000
parents b2115f484edb
children 1ea35226a6de
comparison
equal deleted inserted replaced
229:328ef982d768 230:fbd57d2eeaef
17 import java.sql.ResultSet; 17 import java.sql.ResultSet;
18 import java.sql.SQLException; 18 import java.sql.SQLException;
19 19
20 import java.util.ArrayList; 20 import java.util.ArrayList;
21 import java.util.List; 21 import java.util.List;
22 import java.util.Set;
23 import java.util.Collections;
22 24
23 import javax.sql.DataSource; 25 import javax.sql.DataSource;
24 26
25 import org.apache.log4j.Logger; 27 import org.apache.log4j.Logger;
26 28
55 */ 57 */
56 Artifact reviveArtifact(String factoryName, byte [] bytes); 58 Artifact reviveArtifact(String factoryName, byte [] bytes);
57 59
58 } // interface ArtifactReviver 60 } // interface ArtifactReviver
59 61
62 public interface LockedIdsProvider {
63 Set<Integer> getLockedIds();
64 } // interface LockedIdsProvider
65
60 private static Logger logger = Logger.getLogger(DatabaseCleaner.class); 66 private static Logger logger = Logger.getLogger(DatabaseCleaner.class);
61 67
62 /** 68 /**
63 * Number of artifacts to be loaded at once. Used to 69 * Number of artifacts to be loaded at once. Used to
64 * mitigate the problem of a massive denial of service 70 * mitigate the problem of a massive denial of service
65 * if too many artifacts have died since last cleanup. 71 * if too many artifacts have died since last cleanup.
66 */ 72 */
67 public static final int MAX_ROWS = 50; 73 public static final int MAX_ROWS = 50;
68 74
75 public static final Set<Integer> EMPTY_IDS = Collections.emptySet();
76
69 /** 77 /**
70 * The SQL statement to select the outdated artifacts. 78 * The SQL statement to select the outdated artifacts.
71 */ 79 */
72 public static final String SQL_OUTDATED = 80 public static final String SQL_OUTDATED =
73 SQL.get("artifacts.outdated"); 81 SQL.get("artifacts.outdated");
108 116
109 /** 117 /**
110 * A specialized Id filter which only delete some artifacts. 118 * A specialized Id filter which only delete some artifacts.
111 * This is used to prevent deletion of living artifacts. 119 * This is used to prevent deletion of living artifacts.
112 */ 120 */
113 protected Id.Filter filter; 121 protected LockedIdsProvider lockedIdsProvider;
114 122
115 /** 123 /**
116 * The reviver used to bring the dead artifact on last 124 * The reviver used to bring the dead artifact on last
117 * time back to live to call endOfLife() on them. 125 * time back to live to call endOfLife() on them.
118 */ 126 */
142 * Living artifacts are artifacts which are currently active 150 * Living artifacts are artifacts which are currently active
143 * inside the artifact database. Deleting them in this state 151 * inside the artifact database. Deleting them in this state
144 * would create severe internal problems. 152 * would create severe internal problems.
145 * @param filter 153 * @param filter
146 */ 154 */
147 public void setFilter(Id.Filter filter) { 155 public void setLockedIdsProvider(LockedIdsProvider lockedIdsProvider) {
148 this.filter = filter; 156 this.lockedIdsProvider = lockedIdsProvider;
149 } 157 }
150 158
151 /** 159 /**
152 * External hook to tell the cleaner to wake up before its 160 * External hook to tell the cleaner to wake up before its
153 * regular nap time is over. This is the case when the artifact 161 * regular nap time is over. This is the case when the artifact
177 logger.warn("Cleaner sleep time defaults to " + SLEEP_DEFAULT); 185 logger.warn("Cleaner sleep time defaults to " + SLEEP_DEFAULT);
178 } 186 }
179 return SLEEP_DEFAULT; 187 return SLEEP_DEFAULT;
180 } 188 }
181 189
182 private static final class IdData 190 private static final class IdData {
183 extends Id 191
184 { 192 int id;
185 byte [] data; 193 byte [] data;
186 String factoryName; 194 String factoryName;
187 195
188 public IdData(int id, String factoryName, byte [] data) { 196 public IdData(int id, String factoryName, byte [] data) {
189 super(id); 197 this.id = id;
190 this.factoryName = factoryName; 198 this.factoryName = factoryName;
191 this.data = data; 199 this.data = data;
192 } 200 }
193 } // class IdData 201 } // class IdData
194 202
222 // some dbms like derby do not support LIMIT 230 // some dbms like derby do not support LIMIT
223 // in SQL statements. 231 // in SQL statements.
224 fetchIds.setMaxRows(MAX_ROWS); 232 fetchIds.setMaxRows(MAX_ROWS);
225 233
226 for (;;) { 234 for (;;) {
227 List ids = new ArrayList(); 235 List<IdData> ids = new ArrayList<IdData>();
236
237 Set<Integer> filter = lockedIdsProvider != null
238 ? lockedIdsProvider.getLockedIds()
239 : EMPTY_IDS;
228 240
229 result = fetchIds.executeQuery(); 241 result = fetchIds.executeQuery();
230 242
231 while (result.next()) { 243 while (result.next()) {
232 ids.add(new IdData( 244 int id = result.getInt(1);
233 result.getInt(1), 245 if (!filter.contains(id)) {
234 result.getString(2), 246 ids.add(new IdData(
235 result.getBytes(3))); 247 id,
248 result.getString(2),
249 result.getBytes(3)));
250 }
236 } 251 }
237 252
238 result.close(); result = null; 253 result.close(); result = null;
239 254
240 if (ids.isEmpty()) { 255 if (ids.isEmpty()) {
241 break; 256 break;
242 } 257 }
243 258
244 if (filter != null) {
245 ids = filter.filterIds(ids);
246 }
247
248 for (int i = ids.size()-1; i >= 0; --i) { 259 for (int i = ids.size()-1; i >= 0; --i) {
249 IdData idData = (IdData)ids.get(i); 260 IdData idData = ids.get(i);
250 Artifact artifact = reviver.reviveArtifact( 261 Artifact artifact = reviver.reviveArtifact(
251 idData.factoryName, idData.data); 262 idData.factoryName, idData.data);
252 idData.data = null; 263 idData.data = null;
253 264
254 deleteId.setInt(1, idData.id); 265 deleteId.setInt(1, idData.id);

http://dive4elements.wald.intevation.org