1 5 package org.h2.index; 6 7 import java.sql.SQLException ; 8 9 import org.h2.engine.Constants; 10 import org.h2.engine.Database; 11 import org.h2.engine.Session; 12 import org.h2.message.Message; 13 import org.h2.result.Row; 14 import org.h2.result.SearchRow; 15 import org.h2.store.Storage; 16 import org.h2.table.Column; 17 import org.h2.table.TableData; 18 import org.h2.util.ObjectArray; 19 import org.h2.value.DataType; 20 import org.h2.value.Value; 21 import org.h2.value.ValueLob; 22 23 26 public class ScanIndex extends Index { 27 private int firstFree = -1; 28 private ObjectArray rows = new ObjectArray(); 29 private Storage storage; 30 private TableData tableData; 31 private boolean containsLargeObject; 32 33 public ScanIndex(TableData table, int id, Column[] columns, IndexType indexType) 34 throws SQLException { 35 super(table, id, table.getName() + "_TABLE_SCAN", columns, indexType); 36 tableData = table; 37 Database db = table.getDatabase(); 38 if(!db.isPersistent() || id < 0) { 39 return; 40 } 41 this.storage = db.getStorage(table, id, true); 42 int count = storage.getRecordCount(); 43 rowCount = count; 44 table.setRowCount(count); 45 trace.info("open existing " + table.getName() + " rows: " + count); 46 for(int i=0; i<columns.length; i++) { 47 if(DataType.isLargeObject(columns[i].getType())) { 48 containsLargeObject = true; 49 } 50 } 51 } 52 53 public void remove(Session session) throws SQLException { 54 truncate(session); 55 if(storage != null) { 56 storage.delete(session); 57 } 58 } 59 60 public void truncate(Session session) throws SQLException { 61 if(storage == null) { 62 rows = new ObjectArray(); 63 firstFree = -1; 64 } else { 65 storage.truncate(session); 66 } 67 if(containsLargeObject && tableData.isPersistent()) { 68 ValueLob.removeAllForTable(database, table.getId()); 69 } 70 tableData.setRowCount(0); 71 rowCount = 0; 72 } 73 74 public String getCreateSQL() { 75 return null; 76 } 77 78 public void close(Session session) throws SQLException { 79 if(storage != null) { 80 storage = null; 81 } 82 } 83 84 public Row getRow(int key) throws SQLException { 85 if(storage != null) { 86 return (Row) storage.getRecord(key); 87 } 88 return (Row) rows.get(key); 89 } 90 91 public void add(Session session, Row row) throws SQLException { 92 if(storage != null) { 93 if(containsLargeObject) { 94 for(int i=0; i<row.getColumnCount(); i++) { 95 Value v = row.getValue(i); 96 Value v2 = v.link(database, getId()); 97 session.unlinkAtCommitStop(v2); 98 if(v != v2) { 99 row.setValue(i, v2); 100 } 101 } 102 } 103 storage.addRecord(session, row, Storage.ALLOCATE_POS); 104 } else { 105 if (firstFree == -1) { 106 int key = rows.size(); 107 row.setPos(key); 108 rows.add(row); 109 } else { 110 int key = firstFree; 111 Row free = (Row) rows.get(key); 112 firstFree = free.getPos(); 113 row.setPos(key); 114 rows.set(key, row); 115 } 116 } 117 rowCount++; 118 } 119 120 public void remove(Session session, Row row) throws SQLException { 121 if(storage != null) { 122 storage.removeRecord(session, row.getPos()); 123 if(containsLargeObject) { 124 for(int i=0; i<row.getColumnCount(); i++) { 125 Value v = row.getValue(i); 126 if(v.isLinked()) { 127 session.unlinkAtCommit(v); 128 } 129 } 130 } 131 } else { 132 Row free = new Row(); 133 free.setPos(firstFree); 134 int key = row.getPos(); 135 rows.set(key, free); 136 firstFree = key; 137 } 138 rowCount--; 139 } 140 141 public Cursor find(Session session, SearchRow first, SearchRow last) throws SQLException { 142 return new ScanCursor(this); 143 } 144 145 public int getCost(int[] masks) throws SQLException { 146 int cost = tableData.getRowCount() + Constants.COST_ROW_OFFSET; 147 if(storage != null) { 148 cost *= 10; 149 } 150 return cost; 151 } 152 153 Row getNextRow(Row row) throws SQLException { 154 if(storage == null) { 155 int key; 156 if (row == null) { 157 key = -1; 158 } else { 159 key = row.getPos(); 160 } 161 while (true) { 162 key++; 163 if (key >= rows.size()) { 164 return null; 165 } 166 row = (Row) rows.get(key); 167 if (!row.isEmpty()) { 168 return row; 169 } 170 } 171 } 172 int pos = storage.getNext(row); 173 if (pos < 0) { 174 return null; 175 } 176 return (Row) storage.getRecord(pos); 177 } 178 179 public int getColumnIndex(Column col) { 180 return -1; 182 } 183 184 public void checkRename() throws SQLException { 185 throw Message.getUnsupportedException(); 186 } 187 188 public boolean needRebuild() { 189 return false; 190 } 191 192 public boolean canGetFirstOrLast(boolean first) { 193 return false; 194 } 195 196 public Value findFirstOrLast(Session session, boolean first) throws SQLException { 197 throw Message.getUnsupportedException(); 198 } 199 200 } 201 | Popular Tags |