|                                                                                                              1
 24
 25  package com.mckoi.database;
 26
 27  import com.mckoi.store.*;
 28  import com.mckoi.util.ByteArrayUtil;
 29  import java.io.*;
 30  import java.util.ArrayList
  ; 31  import com.mckoi.debug.DebugLogger;
 32
 33
 41
 42  class StateStore {
 43
 44
 47    private int MAGIC = 0x0BAC8001;
 48
 49
 52    private Store store;
 53
 54
 57    private int table_id;
 58
 59
 64    private MutableArea header_area;
 65
 66
 69    private long vis_p;
 70
 71
 74    private long del_p;
 75
 76
 79    private ArrayList
  visible_list; 80
 81
 84    private ArrayList
  delete_list; 85
 86
 89    private boolean vis_list_change;
 90
 91
 94    private boolean del_list_change;
 95
 96
 99    public StateStore(Store store) {
 100     this.store = store;
 101     vis_list_change = false;
 102     del_list_change = false;
 103   }
 104
 105
 106
 109   private void removeResource(ArrayList
  list, String  name) { 110     int sz = list.size();
 111     for (int i = 0; i < sz; ++i) {
 112       StateResource resource = (StateResource) list.get(i);
 113       if (name.equals(resource.name)) {
 114         list.remove(i);
 115         return;
 116       }
 117     }
 118     throw new RuntimeException
  ("Couldn't find resource '" + name + "' in list."); 119   }
 120
 121
 124   private void readStateResourceList(ArrayList
  list, long pointer) 125                                                           throws IOException {
 126     DataInputStream d_in = new DataInputStream(
 127                                             store.getAreaInputStream(pointer));
 128     int version = d_in.readInt();       int count = (int) d_in.readLong();
 130     for (int i = 0; i < count; ++i) {
 131       long table_id = d_in.readLong();
 132       String
  name = d_in.readUTF(); 133       StateResource resource = new StateResource(table_id, name);
 134       list.add(resource);
 135     }
 136     d_in.close();
 137   }
 138
 139
 142   private void writeStateResourceList(ArrayList
  list, DataOutputStream d_out) 143                                                          throws IOException {
 144     d_out.writeInt(1);
 145     int sz = list.size();
 146     d_out.writeLong(sz);
 147     for (int i = 0; i < sz; ++i) {
 148       StateResource resource = (StateResource) list.get(i);
 149       d_out.writeLong(resource.table_id);
 150       d_out.writeUTF(resource.name);
 151     }
 152   }
 153
 154
 158   private long writeListToStore(ArrayList
  list) throws IOException { 159     ByteArrayOutputStream bout = new ByteArrayOutputStream();
 160     DataOutputStream d_out = new DataOutputStream(bout);
 161     writeStateResourceList(list, d_out);
 162     d_out.flush();
 163     d_out.close();
 164
 165     byte[] buf = bout.toByteArray();
 166
 167     AreaWriter a = store.createArea(buf.length);
 168     long list_p = a.getID();
 169     a.put(buf);
 170     a.finish();
 171
 172     return list_p;
 173   }
 174
 175
 179   public synchronized long create() throws IOException {
 180         AreaWriter vis_tables_area = store.createArea(12);
 182     AreaWriter del_tables_area = store.createArea(12);
 183     vis_p = vis_tables_area.getID();
 184     del_p = del_tables_area.getID();
 185
 186         vis_tables_area.putInt(1);
 188     vis_tables_area.putLong(0);
 189     vis_tables_area.finish();
 190     del_tables_area.putInt(1);
 191     del_tables_area.putLong(0);
 192     del_tables_area.finish();
 193
 194         AreaWriter header_writer = store.createArea(32);
 196     long header_p = header_writer.getID();
 197     header_writer.putInt(MAGIC);
 198     header_writer.putInt(0);
 199     header_writer.putLong(0);
 200     header_writer.putLong(vis_p);
 201     header_writer.putLong(del_p);
 202     header_writer.finish();
 203
 204     header_area = store.getMutableArea(header_p);
 205
 206         table_id = 0;
 208
 209     visible_list = new ArrayList
  (); 210     delete_list = new ArrayList
  (); 211
 212         return header_p;
 214   }
 215
 216
 220   public synchronized void init(long header_p) throws IOException {
 221     header_area = store.getMutableArea(header_p);
 222     int mag_value = header_area.getInt();
 223     if (mag_value != MAGIC) {
 224       throw new IOException("Magic value for state header area is incorrect.");
 225     }
 226     if (header_area.getInt() != 0) {
 227       throw new IOException("Unknown version for state header area.");
 228     }
 229     table_id = (int) header_area.getLong();
 230     vis_p = header_area.getLong();
 231     del_p = header_area.getLong();
 232
 233         visible_list = new ArrayList
  (); 235     delete_list = new ArrayList
  (); 236
 237         readStateResourceList(visible_list, vis_p);
 239     readStateResourceList(delete_list, del_p);
 240
 241   }
 242
 243
 248   public synchronized long convert(File legacy_sf, DebugLogger debug)
 249                                                            throws IOException {
 250         long header_p = create();
 252
 253         FixedSizeDataStore state_file =
 255                                 new FixedSizeDataStore(legacy_sf, 507, debug);
 256     state_file.open(true);
 257
 258         byte[] reserved_buffer = new byte[64];
 260     state_file.readReservedBuffer(reserved_buffer, 0, 64);
 261
 262         int tables_sector = ByteArrayUtil.getInt(reserved_buffer, 4);
 264     InputStream sin = state_file.getSectorInputStream(tables_sector);
 265     DataInputStream din = new DataInputStream(sin);
 266     int vtver = din.readInt();       int size = din.readInt();
 268         for (int i = 0 ; i < size; ++i) {
 270       int table_id = din.readInt();
 271       String
  resource_name = din.readUTF(); 272             if (!resource_name.startsWith(":")) {
 274         resource_name = ":1" + resource_name;
 275       }
 276             addVisibleResource(new StateResource(table_id, resource_name));
 278     }
 279     din.close();
 280
 281         int dropped_sector = ByteArrayUtil.getInt(reserved_buffer, 12);
 283     if (dropped_sector > -1) {
 284       sin = state_file.getSectorInputStream(dropped_sector);
 285       din = new DataInputStream(sin);
 286       int dsver = din.readInt();        size = din.readInt();
 288             for (int i = 0; i < size; ++i) {
 290         String
  resource_name = din.readUTF(); 291                 if (!resource_name.startsWith(":")) {
 293           resource_name = ":1" + resource_name;
 294         }
 295                 addDeleteResource(new StateResource(-1, resource_name));
 297       }
 298       din.close();
 299
 300     }
 301
 302         int state_sector = ByteArrayUtil.getInt(reserved_buffer, 8);
 304     sin = state_file.getSectorInputStream(state_sector);
 305     din = new DataInputStream(sin);
 306     din.readInt();       int conv_table_id = din.readInt();
 308     din.close();
 309
 310         state_file.close();
 312
 313         header_area.position(8);
 315     header_area.putLong(conv_table_id);
 316         header_area.checkOut();
 318
 319         commit();
 321
 322         return header_p;
 324   }
 325
 326
 329   public synchronized int nextTableID() throws IOException {
 330     int cur_counter = table_id;
 331     ++table_id;
 332
 333     try {
 334       store.lockForWrite();
 335
 336             header_area.position(8);
 338       header_area.putLong(table_id);
 339             header_area.checkOut();
 341
 342     }
 343     finally {
 344       store.unlockForWrite();
 345     }
 346
 347     return cur_counter;
 348   }
 349
 350
 354   public synchronized StateResource[] getVisibleList() {
 355     return (StateResource[])
 356                  visible_list.toArray(new StateResource[visible_list.size()]);
 357   }
 358
 359
 363   public synchronized StateResource[] getDeleteList() {
 364     return (StateResource[])
 365                    delete_list.toArray(new StateResource[delete_list.size()]);
 366   }
 367
 368
 372   public synchronized boolean containsVisibleResource(int table_id) {
 373     int sz = visible_list.size();
 374     for (int i = 0; i < sz; ++i) {
 375       if (((StateResource) visible_list.get(i)).table_id == table_id) {
 376         return true;
 377       }
 378     }
 379     return false;
 380   }
 381
 382
 387   public synchronized void addVisibleResource(StateResource resource) {
 388     visible_list.add(resource);
 389     vis_list_change = true;
 390   }
 391
 392
 397   public synchronized void addDeleteResource(StateResource resource) {
 398     delete_list.add(resource);
 399     del_list_change = true;
 400   }
 401
 402
 407   public synchronized void removeVisibleResource(String
  name) { 408     removeResource(visible_list, name);
 409     vis_list_change = true;
 410   }
 411
 412
 417   public synchronized void removeDeleteResource(String
  name) { 418     removeResource(delete_list, name);
 419     del_list_change = true;
 420   }
 421
 422
 428   public synchronized boolean commit() throws IOException {
 429     boolean changes = false;
 430     long new_vis_p = vis_p;
 431     long new_del_p = del_p;
 432
 433     try {
 434       store.lockForWrite();
 435
 436             if (vis_list_change) {
 438         new_vis_p = writeListToStore(visible_list);
 439         vis_list_change = false;
 440         changes = true;
 441       }
 442       if (del_list_change) {
 443         new_del_p = writeListToStore(delete_list);
 444         del_list_change = false;
 445         changes = true;
 446       }
 447             if (changes) {
 449         header_area.position(16);
 450         header_area.putLong(new_vis_p);
 451         header_area.putLong(new_del_p);
 452                 header_area.checkOut();
 454         if (vis_p != new_vis_p) {
 455           store.deleteArea(vis_p);
 456           vis_p = new_vis_p;
 457         }
 458         if (del_p != new_del_p) {
 459           store.deleteArea(del_p);
 460           del_p = new_del_p;
 461         }
 462       }
 463
 464     }
 465     finally {
 466       store.unlockForWrite();
 467     }
 468
 469     return changes;
 470   }
 471
 472
 474
 478   static class StateResource {
 479
 480
 483     long table_id;
 484
 485
 489     String
  name; 490
 491     public StateResource(long table_id, String
  name) { 492       this.table_id = table_id;
 493       this.name = name;
 494     }
 495
 496   }
 497
 498 }
 499
 500
                                                                                                                                                                                                             |                                                                       
 
 
 
 
 
                                                                                   Popular Tags                                                                                                                                                                                              |