提交 c1a0982e authored 作者: Thomas Mueller's avatar Thomas Mueller

New experimental page store.

上级 724518e5
......@@ -419,6 +419,8 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>MySQL compatibility: DatabaseMetaData.stores*() methods should return the same values. Test with SquirrelSQL.
</li><li>MS SQL Server compatibility: support DATEPART syntax.
</li><li>Oracle compatibility: support CREATE OR REPLACE VIEW syntax.
</li><li>Sybase/DB2/Oracle compatibility: support out parameters in stored procedures - See http://code.google.com/p/h2database/issues/detail?id=83
</li><li>Support INTERVAL data type (see Oracle and others).
</li></ul>
<h2>Not Planned</h2>
......
......@@ -97,7 +97,7 @@ public class Set extends Prepared {
CompareMode compareMode;
StringBuilder buff = new StringBuilder(stringValue);
if (stringValue.equals(CompareMode.OFF)) {
compareMode = new CompareMode(null, 0);
compareMode = CompareMode.getInstance(null, 0);
} else {
int strength = getIntValue();
buff.append(" STRENGTH ");
......@@ -110,7 +110,7 @@ public class Set extends Prepared {
} else if (strength == Collator.TERTIARY) {
buff.append("TERTIARY");
}
compareMode = new CompareMode(stringValue, strength);
compareMode = CompareMode.getInstance(stringValue, strength);
}
addOrUpdateSetting(name, buff.toString(), 0);
database.setCompareMode(compareMode);
......
......@@ -330,7 +330,8 @@ public class ConstraintReferential extends Constraint {
}
private boolean found(Session session, Index searchIndex, SearchRow check, Row excluding) throws SQLException {
searchIndex.getTable().lock(session, false, false);
Table table = searchIndex.getTable();
table.lock(session, false, false);
Cursor cursor = searchIndex.find(session, check, check);
while (cursor.next()) {
SearchRow found;
......@@ -344,7 +345,7 @@ public class ConstraintReferential extends Constraint {
int idx = cols[i].getColumnId();
Value c = check.getValue(idx);
Value f = found.getValue(idx);
if (database.compareTypeSave(c, f) != 0) {
if (table.compareTypeSave(c, f) != 0) {
allEqual = false;
break;
}
......
......@@ -169,7 +169,7 @@ public class Database implements DataHandler {
private boolean reconnectChangePending;
public Database(String name, ConnectionInfo ci, String cipher) throws SQLException {
this.compareMode = new CompareMode(null, 0);
this.compareMode = CompareMode.getInstance(null, 0);
this.persistent = ci.isPersistent();
this.filePasswordHash = ci.getFilePasswordHash();
this.databaseName = name;
......
......@@ -291,7 +291,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
}
return SortOrder.compareNull(aNull, bNull, sortType);
}
int comp = database.compareTypeSave(a, b);
int comp = table.compareTypeSave(a, b);
if ((sortType & SortOrder.DESCENDING) != 0) {
comp = -comp;
}
......
......@@ -21,6 +21,7 @@ import org.h2.index.PageScanIndex;
import org.h2.log.SessionState;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.message.TraceSystem;
import org.h2.result.Row;
import org.h2.schema.Schema;
import org.h2.table.Column;
......@@ -35,6 +36,7 @@ import org.h2.util.FileUtils;
import org.h2.util.New;
import org.h2.util.ObjectArray;
import org.h2.util.StringUtils;
import org.h2.value.CompareMode;
import org.h2.value.Value;
import org.h2.value.ValueInt;
import org.h2.value.ValueString;
......@@ -174,7 +176,7 @@ public class PageStore implements CacheWriter {
this.database = database;
trace = database.getTrace(Trace.PAGE_STORE);
int test;
// trace.setLevel(TraceSystem.DEBUG);
trace.setLevel(TraceSystem.DEBUG);
this.cacheSize = cacheSizeDefault;
String cacheType = database.getCacheType();
this.cache = CacheLRU.getCache(this, cacheType, cacheSize);
......@@ -809,8 +811,8 @@ public class PageStore implements CacheWriter {
cols.add(new Column("TYPE", Value.INT));
cols.add(new Column("PARENT", Value.INT));
cols.add(new Column("HEAD", Value.INT));
cols.add(new Column("OPTIONS", Value.STRING));
cols.add(new Column("COLUMNS", Value.STRING));
// new CompareMode()
metaSchema = new Schema(database, 0, "", null, true);
int headPos = metaTableRootPageId;
metaTable = new TableData(metaSchema, "PAGE_INDEX",
......@@ -843,7 +845,8 @@ public class PageStore implements CacheWriter {
int type = row.getValue(1).getInt();
int parent = row.getValue(2).getInt();
int headPos = row.getValue(3).getInt();
String columnList = row.getValue(4).getString();
String options = row.getValue(4).getString();
String columnList = row.getValue(5).getString();
String[] columns = StringUtils.arraySplit(columnList, ',', false);
IndexType indexType = IndexType.createNonUnique(true);
Index meta;
......@@ -857,6 +860,9 @@ public class PageStore implements CacheWriter {
columnArray.add(col);
}
TableData table = new TableData(metaSchema, "T" + id, id, columnArray, true, true, false, headPos, session);
String[] ops = StringUtils.arraySplit(options, ',', true);
CompareMode mode = CompareMode.getInstance(ops[0], Integer.parseInt(ops[1]));
table.setCompareMode(mode);
meta = table.getScanIndex(session);
} else {
PageScanIndex p = (PageScanIndex) metaObjects.get(parent);
......@@ -889,16 +895,20 @@ public class PageStore implements CacheWriter {
columnIndexes[i] = String.valueOf(columns[i].getColumnId());
}
String columnList = StringUtils.arrayCombine(columnIndexes, ',');
addMeta(index.getId(), type, index.getTable().getId(), index.getHeadPos(), columnList, session);
Table table = index.getTable();
CompareMode mode = table.getCompareMode();
String options = mode.getName()+ "," + mode.getStrength();
addMeta(index.getId(), type, table.getId(), index.getHeadPos(), options, columnList, session);
}
private void addMeta(int id, int type, int parent, int headPos, String columnList, Session session) throws SQLException {
private void addMeta(int id, int type, int parent, int headPos, String options, String columnList, Session session) throws SQLException {
Row row = metaTable.getTemplateRow();
row.setValue(0, ValueInt.get(id));
row.setValue(1, ValueInt.get(type));
row.setValue(2, ValueInt.get(parent));
row.setValue(3, ValueInt.get(headPos));
row.setValue(4, ValueString.get(columnList));
row.setValue(4, ValueString.get(options));
row.setValue(5, ValueString.get(columnList));
row.setPos(id + 1);
metaIndex.add(session, row);
}
......
......@@ -35,6 +35,7 @@ import org.h2.schema.Sequence;
import org.h2.schema.TriggerObject;
import org.h2.util.New;
import org.h2.util.ObjectArray;
import org.h2.value.CompareMode;
import org.h2.value.DataType;
import org.h2.value.Value;
import org.h2.value.ValueNull;
......@@ -85,6 +86,11 @@ public abstract class Table extends SchemaObjectBase {
*/
protected int memoryPerRow;
/**
* The compare mode used for this table.
*/
protected CompareMode compareMode;
private final HashMap<String, Column> columnMap = New.hashMap();
private boolean persistIndexes;
private boolean persistData;
......@@ -100,6 +106,7 @@ public abstract class Table extends SchemaObjectBase {
initSchemaObjectBase(schema, id, name, Trace.TABLE);
this.persistIndexes = persistIndexes;
this.persistData = persistData;
compareMode = schema.getDatabase().getCompareMode();
}
public void rename(String newName) throws SQLException {
......@@ -904,4 +911,21 @@ public abstract class Table extends SchemaObjectBase {
return persistData;
}
/**
* Compare two values with the current comparison mode. The values must be
* of the same type.
*
* @param a the first value
* @param b the second value
* @return 0 if both values are equal, -1 if the first value is smaller, and
* 1 otherwise
*/
public int compareTypeSave(Value a, Value b) throws SQLException {
return a.compareTypeSave(b, compareMode);
}
public CompareMode getCompareMode() {
return compareMode;
}
}
......@@ -43,6 +43,7 @@ import org.h2.util.New;
import org.h2.util.ObjectArray;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils;
import org.h2.value.CompareMode;
import org.h2.value.DataType;
import org.h2.value.Value;
......@@ -699,4 +700,8 @@ public class TableData extends Table implements RecordReader {
return scanIndex.getRowCountApproximation();
}
public void setCompareMode(CompareMode compareMode) {
this.compareMode = compareMode;
}
}
......@@ -27,19 +27,16 @@ public class CompareMode {
*/
public static final String OFF = "OFF";
private final Collator collator;
private static CompareMode lastUsed;
private final String name;
private final int strength;
private final Collator collator;
private final SmallLRUCache<String, CollationKey> collationKeys;
/**
* Create a new compare mode with the given collator and cache size.
* The cache is used to speed up comparison when using a collator;
* CollationKey objects are cached.
*
* @param name the collation name or null
* @param strength the collation strength
*/
public CompareMode(String name, int strength) {
private CompareMode(String name, int strength) {
this.name = name;
this.strength = strength;
this.collator = CompareMode.getCollator(name);
int cacheSize = 0;
if (collator != null) {
......@@ -51,7 +48,28 @@ public class CompareMode {
} else {
collationKeys = null;
}
this.name = name == null ? OFF : name;
}
/**
* Create a new compare mode with the given collator and strength. If
* required, a new CompareMode is created, or if possible the last one is
* returned. A cache is used to speed up comparison when using a collator;
* CollationKey objects are cached.
*
* @param name the collation name or null
* @param strength the collation strength
* @return the compare mode
*/
public static CompareMode getInstance(String name, int strength) {
if (lastUsed != null) {
if (StringUtils.equals(lastUsed.name, name)) {
if (lastUsed.strength == strength) {
return lastUsed;
}
}
}
lastUsed = new CompareMode(name, strength);
return lastUsed;
}
/**
......@@ -178,7 +196,11 @@ public class CompareMode {
}
public String getName() {
return name;
return name == null ? OFF : name;
}
public int getStrength() {
return strength;
}
}
......@@ -295,12 +295,9 @@ java org.h2.test.TestAll timer
shell tool: document encoding problem. mac: use
java -Dfile.encoding=UTF-8;
BaseIndex or TableData should have its own compareMode
(default is: Database.compareMode when created).
standard: COLLATE for each column (MySQL, SQL Server)
TableData should have its own compareMode
(copy of Database.compareMode when created).
stored in the pageStore as well.
check syntax in other databases.
this mean changing the collation is allowed if there are tables.
test case for running out of disk space (using a special file system)
......
......@@ -7,6 +7,7 @@
package org.h2.test.unit;
import java.sql.SQLException;
import java.text.Collator;
import org.h2.expression.CompareLike;
import org.h2.test.TestBase;
......@@ -27,7 +28,24 @@ public class TestPattern extends TestBase {
}
public void test() throws SQLException {
CompareMode mode = new CompareMode(null, 0);
testCompareModeReuse();
testPattern();
}
private void testCompareModeReuse() {
CompareMode mode1, mode2;
mode1 = CompareMode.getInstance(null, 0);
mode2 = CompareMode.getInstance(null, 0);
assertTrue(mode1 == mode2);
mode1 = CompareMode.getInstance("DE", Collator.SECONDARY);
assertFalse(mode1 == mode2);
mode2 = CompareMode.getInstance("DE", Collator.SECONDARY);
assertTrue(mode1 == mode2);
}
private void testPattern() throws SQLException {
CompareMode mode = CompareMode.getInstance(null, 0);
CompareLike comp = new CompareLike(mode, null, null, null, false);
test(comp, "B", "%_");
test(comp, "A", "A%");
......
......@@ -31,7 +31,7 @@ import org.h2.value.ValueInt;
*/
public class TestValueHashMap extends TestBase implements DataHandler {
CompareMode compareMode = new CompareMode(null, 0);
CompareMode compareMode = CompareMode.getInstance(null, 0);
/**
* Run just this test.
......
......@@ -590,3 +590,4 @@ overall httpdocs tigris eclemma separates underscore yajsw she her truncating
relocating smtps smtp osde joist catching guesses delimiters shortlist sheet
rowspan cheat partitioning datepart dreamsource toussi locates fred
longnvarchar collate localdb nan bootclasspath bcp retrotranslator iterable
ops
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论