1 30 31 32 package org.hsqldb; 33 34 import org.hsqldb.HsqlNameManager.HsqlName; 35 import org.hsqldb.lib.IntKeyHashMap; 36 import org.hsqldb.lib.IntKeyIntValueHashMap; 37 import org.hsqldb.lib.IntValueHashMap; 38 import org.hsqldb.lib.Iterator; 39 40 77 final class CompiledStatementManager { 78 79 83 private Database database; 84 85 86 private IntKeyHashMap schemaMap; 87 88 89 private IntKeyHashMap sqlLookup; 90 91 92 private IntKeyHashMap csidMap; 93 94 95 private IntKeyHashMap sessionUseMap; 96 97 98 private IntKeyIntValueHashMap useMap; 99 100 104 private int next_cs_id; 105 106 112 CompiledStatementManager(Database database) { 113 114 this.database = database; 115 schemaMap = new IntKeyHashMap(); 116 sqlLookup = new IntKeyHashMap(); 117 csidMap = new IntKeyHashMap(); 118 sessionUseMap = new IntKeyHashMap(); 119 useMap = new IntKeyIntValueHashMap(); 120 next_cs_id = 0; 121 } 122 123 126 synchronized void reset() { 127 128 schemaMap.clear(); 129 sqlLookup.clear(); 130 csidMap.clear(); 131 sessionUseMap.clear(); 132 useMap.clear(); 133 134 next_cs_id = 0; 135 } 136 137 142 synchronized void resetStatements() { 143 144 Iterator it = csidMap.values().iterator(); 145 146 while (it.hasNext()) { 147 CompiledStatement cs = (CompiledStatement) it.next(); 148 149 cs.clearVariables(); 150 } 151 } 152 153 158 private int nextID() { 159 160 next_cs_id++; 161 162 return next_cs_id; 163 } 164 165 175 private int getStatementID(HsqlName schema, String sql) { 176 177 IntValueHashMap sqlMap = 178 (IntValueHashMap) schemaMap.get(schema.hashCode()); 179 180 if (sqlMap == null) { 181 return -1; 182 } 183 184 return sqlMap.get(sql, -1); 185 } 186 187 196 synchronized CompiledStatement getStatement(Session session, int csid) { 197 198 CompiledStatement cs = (CompiledStatement) csidMap.get(csid); 199 200 if (cs == null) { 201 return null; 202 } 203 204 if (!cs.isValid) { 205 String sql = (String ) sqlLookup.get(csid); 206 207 try { 209 cs = compileSql(session, sql, cs.schemaHsqlName.name); 210 cs.id = csid; 211 212 csidMap.put(csid, cs); 213 } catch (Throwable t) { 214 freeStatement(csid, session.getId(), true); 215 216 return null; 217 } 218 } 219 220 return cs; 221 } 222 223 232 private void linkSession(int csid, int sid) { 233 234 IntKeyIntValueHashMap scsMap; 235 236 scsMap = (IntKeyIntValueHashMap) sessionUseMap.get(sid); 237 238 if (scsMap == null) { 239 scsMap = new IntKeyIntValueHashMap(); 240 241 sessionUseMap.put(sid, scsMap); 242 } 243 244 int count = scsMap.get(csid, 0); 245 246 scsMap.put(csid, count + 1); 247 248 if (count == 0) { 249 useMap.put(csid, useMap.get(csid, 0) + 1); 250 } 251 } 252 253 265 private int registerStatement(int csid, CompiledStatement cs) { 266 267 if (csid < 0) { 268 csid = nextID(); 269 270 int schemaid = cs.schemaHsqlName.hashCode(); 271 IntValueHashMap sqlMap = 272 (IntValueHashMap) schemaMap.get(schemaid); 273 274 if (sqlMap == null) { 275 sqlMap = new IntValueHashMap(); 276 277 schemaMap.put(schemaid, sqlMap); 278 } 279 280 sqlMap.put(cs.sql, csid); 281 sqlLookup.put(csid, cs.sql); 282 } 283 284 cs.id = csid; 285 286 csidMap.put(csid, cs); 287 288 return csid; 289 } 290 291 301 void freeStatement(int csid, int sid, boolean freeAll) { 302 303 if (csid == -1) { 304 305 return; 307 } 308 309 IntKeyIntValueHashMap scsMap = 310 (IntKeyIntValueHashMap) sessionUseMap.get(sid); 311 312 if (scsMap == null) { 313 314 return; 316 } 317 318 int sessionUseCount = scsMap.get(csid, 0); 319 320 if (sessionUseCount == 0) { 321 322 } else if (sessionUseCount == 1 || freeAll) { 324 scsMap.remove(csid); 325 326 int usecount = useMap.get(csid, 0); 327 328 if (usecount == 0) { 329 330 } else if (usecount == 1) { 332 CompiledStatement cs = 333 (CompiledStatement) csidMap.remove(csid); 334 335 if (cs != null) { 336 int schemaid = cs.schemaHsqlName.hashCode(); 337 IntValueHashMap sqlMap = 338 (IntValueHashMap) schemaMap.get(schemaid); 339 String sql = (String ) sqlLookup.remove(csid); 340 341 sqlMap.remove(sql); 342 } 343 344 useMap.remove(csid); 345 } else { 346 useMap.put(csid, usecount - 1); 347 } 348 } else { 349 scsMap.put(csid, sessionUseCount - 1); 350 } 351 } 352 353 362 synchronized void removeSession(int sid) { 363 364 IntKeyIntValueHashMap scsMap; 365 int csid; 366 Iterator i; 367 368 scsMap = (IntKeyIntValueHashMap) sessionUseMap.remove(sid); 369 370 if (scsMap == null) { 371 return; 372 } 373 374 i = scsMap.keySet().iterator(); 375 376 while (i.hasNext()) { 377 csid = i.nextInt(); 378 379 int usecount = useMap.get(csid, 1) - 1; 380 381 if (usecount == 0) { 382 CompiledStatement cs = 383 (CompiledStatement) csidMap.remove(csid); 384 385 if (cs != null) { 386 int schemaid = cs.schemaHsqlName.hashCode(); 387 IntValueHashMap sqlMap = 388 (IntValueHashMap) schemaMap.get(schemaid); 389 String sql = (String ) sqlLookup.remove(csid); 390 391 sqlMap.remove(sql); 392 } 393 394 useMap.remove(csid); 395 } else { 396 useMap.put(csid, usecount); 397 } 398 } 399 } 400 401 425 synchronized CompiledStatement compile(Session session, 426 String sql) throws Throwable { 427 428 int csid = getStatementID(session.currentSchema, sql); 429 CompiledStatement cs = (CompiledStatement) csidMap.get(csid); 430 431 if (cs == null ||!cs.isValid ||!session.isAdmin()) { 432 cs = compileSql(session, sql, session.currentSchema.name); 433 csid = registerStatement(csid, cs); 434 } 435 436 linkSession(csid, session.getId()); 437 438 return cs; 439 } 440 441 private CompiledStatement compileSql(Session session, String sql, 442 String schemaName) throws Throwable { 443 444 Session sys = database.sessionManager.getSysSession(schemaName, 445 session.getUser()); 446 447 return sys.sqlCompileStatement(sql); 448 } 449 } 450 | Popular Tags |