1 24 25 package com.mckoi.database; 26 27 import com.mckoi.util.IntegerVector; 28 import com.mckoi.util.BlockIntegerList; 29 import java.util.ArrayList ; 30 31 47 48 final class TransactionJournal { 49 50 53 static byte TABLE_ADD = 1; static byte TABLE_REMOVE = 2; static byte TABLE_CREATE = 3; static byte TABLE_DROP = 4; static byte TABLE_CONSTRAINT_ALTER = 5; 64 67 private int journal_entries; 68 69 78 private IntegerVector touched_tables; 79 80 84 private byte[] command_journal; 85 86 91 private IntegerVector command_parameters; 92 93 97 private boolean has_added_table_rows, has_removed_table_rows, 98 has_created_tables, has_dropped_tables, has_constraint_alterations; 99 100 103 TransactionJournal() { 104 journal_entries = 0; 105 command_journal = new byte[16]; 106 command_parameters = new IntegerVector(32); 107 touched_tables = new IntegerVector(8); 108 109 has_added_table_rows = false; 110 has_removed_table_rows = false; 111 has_created_tables = false; 112 has_dropped_tables = false; 113 has_constraint_alterations = false; 114 } 115 116 119 private void addCommand(byte command) { 120 if (journal_entries >= command_journal.length) { 121 int grow_size = Math.min(4000, journal_entries); 123 byte[] new_command_journal = new byte[journal_entries + grow_size]; 124 System.arraycopy(command_journal, 0, new_command_journal, 0, 125 journal_entries); 126 command_journal = new_command_journal; 127 } 128 129 command_journal[journal_entries] = command; 130 ++journal_entries; 131 } 132 133 136 private void addParameter(int param) { 137 command_parameters.addInt(param); 138 } 139 140 143 synchronized void entryAddTouchedTable(int table_id) { 144 int pos = touched_tables.sortedIndexOf(table_id); 145 if (pos < touched_tables.size() && 147 touched_tables.intAt(pos) == table_id) { 148 return; 149 } 150 if (pos >= touched_tables.size()) { 153 touched_tables.addInt(table_id); 154 } 155 else { 156 touched_tables.insertIntAt(table_id, pos); 158 } 159 } 160 161 165 synchronized void entryAddTableRow(int table_id, int row_index) { 166 addCommand(TABLE_ADD); 168 addParameter(table_id); 169 addParameter(row_index); 170 } 171 172 176 synchronized void entryRemoveTableRow(int table_id, int row_index) { 177 addCommand(TABLE_REMOVE); 179 addParameter(table_id); 180 addParameter(row_index); 181 } 182 183 187 synchronized void entryTableCreate(int table_id) { 188 has_created_tables = true; 189 addCommand(TABLE_CREATE); 190 addParameter(table_id); 191 } 192 193 197 synchronized void entryTableDrop(int table_id) { 198 has_dropped_tables = true; 199 addCommand(TABLE_DROP); 200 addParameter(table_id); 201 } 202 203 207 synchronized void entryTableConstraintAlter(int table_id) { 208 has_constraint_alterations = true; 209 addCommand(TABLE_CONSTRAINT_ALTER); 210 addParameter(table_id); 211 } 212 213 214 225 MasterTableJournal[] makeMasterTableJournals() { 226 ArrayList table_journals = new ArrayList (); 227 int param_index = 0; 228 229 MasterTableJournal master_journal = null; 230 231 for (int i = 0 ; i < journal_entries; ++i) { 232 byte c = command_journal[i]; 233 if (c == TABLE_ADD || c == TABLE_REMOVE) { 234 int table_id = command_parameters.intAt(param_index); 235 int row_index = command_parameters.intAt(param_index + 1); 236 param_index += 2; 237 238 if (master_journal == null || 240 master_journal.getTableID() != table_id) { 241 int size = table_journals.size(); 243 master_journal = null; 244 for (int n = 0; n < size && master_journal == null; ++n) { 245 MasterTableJournal test_journal = 246 (MasterTableJournal) table_journals.get(n); 247 if (test_journal.getTableID() == table_id) { 248 master_journal = test_journal; 249 } 250 } 251 252 if (master_journal == null) { 254 master_journal = new MasterTableJournal(table_id); 255 table_journals.add(master_journal); 256 } 257 258 } 259 260 master_journal.addEntry(c, row_index); 262 263 } 264 else if (c == TABLE_CREATE || 265 c == TABLE_DROP || 266 c == TABLE_CONSTRAINT_ALTER) { 267 param_index += 1; 268 } 269 else { 270 throw new Error ("Unknown journal command."); 271 } 272 } 273 274 return (MasterTableJournal[]) table_journals.toArray( 276 new MasterTableJournal[table_journals.size()]); 277 278 } 279 280 283 IntegerVector getTablesDropped() { 284 IntegerVector dropped_tables = new IntegerVector(); 285 if (!has_dropped_tables) { 287 return dropped_tables; 288 } 289 290 int param_index = 0; 291 for (int i = 0 ; i < journal_entries; ++i) { 292 byte c = command_journal[i]; 293 if (c == TABLE_ADD || c == TABLE_REMOVE) { 294 param_index += 2; 295 } 296 else if (c == TABLE_CREATE || c == TABLE_CONSTRAINT_ALTER) { 297 param_index += 1; 298 } 299 else if (c == TABLE_DROP) { 300 dropped_tables.addInt(command_parameters.intAt(param_index)); 301 param_index += 1; 302 } 303 else { 304 throw new Error ("Unknown journal command."); 305 } 306 } 307 308 return dropped_tables; 309 } 310 311 314 IntegerVector getTablesCreated() { 315 IntegerVector created_tables = new IntegerVector(); 316 if (!has_created_tables) { 318 return created_tables; 319 } 320 321 int param_index = 0; 322 for (int i = 0 ; i < journal_entries; ++i) { 323 byte c = command_journal[i]; 324 if (c == TABLE_ADD || c == TABLE_REMOVE) { 325 param_index += 2; 326 } 327 else if (c == TABLE_DROP || c == TABLE_CONSTRAINT_ALTER) { 328 param_index += 1; 329 } 330 else if (c == TABLE_CREATE) { 331 created_tables.addInt(command_parameters.intAt(param_index)); 332 param_index += 1; 333 } 334 else { 335 throw new Error ("Unknown journal command."); 336 } 337 } 338 339 return created_tables; 340 } 341 342 346 IntegerVector getTablesConstraintAltered() { 347 IntegerVector caltered_tables = new IntegerVector(); 348 if (!has_constraint_alterations) { 350 return caltered_tables; 351 } 352 353 int param_index = 0; 354 for (int i = 0 ; i < journal_entries; ++i) { 355 byte c = command_journal[i]; 356 if (c == TABLE_ADD || c == TABLE_REMOVE) { 357 param_index += 2; 358 } 359 else if (c == TABLE_DROP || c == TABLE_CREATE) { 360 param_index += 1; 361 } 362 else if (c == TABLE_CONSTRAINT_ALTER) { 363 caltered_tables.addInt(command_parameters.intAt(param_index)); 364 param_index += 1; 365 } 366 else { 367 throw new Error ("Unknown journal command."); 368 } 369 } 370 371 return caltered_tables; 372 } 373 374 375 } 376 | Popular Tags |