1 24 25 package com.mckoi.database; 26 27 import com.mckoi.util.BlockIntegerList; 28 import com.mckoi.debug.*; 29 import java.io.IOException ; 30 31 40 41 final class MasterTableGarbageCollector { 42 43 46 private MasterTableDataSource data_source; 47 48 52 private boolean full_sweep_due; 53 54 61 private BlockIntegerList deleted_rows; 62 63 66 private long last_garbage_success_event; 67 private long last_garbage_try_event; 68 69 72 MasterTableGarbageCollector(MasterTableDataSource data_source) { 73 this.data_source = data_source; 74 full_sweep_due = false; 75 deleted_rows = new BlockIntegerList(); 76 last_garbage_success_event = System.currentTimeMillis(); 77 last_garbage_try_event = -1; 78 } 79 80 83 public final DebugLogger Debug() { 84 return data_source.Debug(); 85 } 86 87 94 void markRowAsDeleted(int row_index) { 95 if (full_sweep_due == false) { 96 boolean b = deleted_rows.uniqueInsertSort(row_index); 97 if (b == false) { 98 throw new Error ("Row marked twice for deletion."); 99 } 100 } 101 } 102 103 110 void markFullSweep() { 111 full_sweep_due = true; 112 if (deleted_rows.size() > 0) { 113 deleted_rows = new BlockIntegerList(); 114 } 115 } 116 117 126 void performCollectionEvent(boolean force) { 127 128 try { 129 int check_count = 0; 130 int delete_count = 0; 131 132 synchronized (data_source) { 135 136 if (data_source.isClosed()) { 137 return; 138 } 139 140 if (force || 144 (!data_source.isRootLocked() && 145 !data_source.hasTransactionChangesPending())) { 146 147 last_garbage_success_event = System.currentTimeMillis(); 148 last_garbage_try_event = -1; 149 150 if (full_sweep_due) { 152 int raw_row_count = data_source.rawRowCount(); 153 for (int i = 0; i < raw_row_count; ++i) { 154 boolean b = data_source.hardCheckAndReclaimRow(i); 156 if (b) { 157 ++delete_count; 158 } 159 ++check_count; 160 } 161 full_sweep_due = false; 162 } 163 else { 164 int size = deleted_rows.size(); 166 if (size > 0) { 167 for (int i = 0; i < size; ++i) { 169 int row_index = deleted_rows.get(i); 170 data_source.hardRemoveRow(row_index); 172 ++delete_count; 173 ++check_count; 174 } 175 } 176 deleted_rows = new BlockIntegerList(); 177 } 178 179 if (check_count > 0) { 180 if (Debug().isInterestedIn(Lvl.INFORMATION)) { 181 Debug().write(Lvl.INFORMATION, this, 182 "Row GC: [" + data_source.getName() + 183 "] check_count=" + check_count + 184 " delete count=" + delete_count); 185 Debug().write(Lvl.INFORMATION, this, 186 "GC row sweep deleted " + delete_count + " rows."); 187 } 188 } 189 190 } 192 } } 194 catch (IOException e) { 195 Debug().writeException(e); 196 } 197 198 } 199 200 201 203 209 private class CollectionEvent implements Runnable { 210 211 public void run() { 212 performCollectionEvent(false); 213 } 214 215 } 216 217 } 218 | Popular Tags |