Skip to content

Commit 0430025

Browse files
committed
Resolve #77 SQLiteCursor handle hash collision in column name
1 parent da119c1 commit 0430025

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

sqlite-android/src/main/java/io/requery/android/database/sqlite/SQLiteCursor.java

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import io.requery.android.database.AbstractWindowedCursor;
2323
import io.requery.android.database.CursorWindow;
2424

25+
import java.util.HashMap;
26+
2527
/**
2628
* A Cursor implementation that exposes results from a query on a {@link SQLiteDatabase}.
2729
*
@@ -48,7 +50,8 @@ public class SQLiteCursor extends AbstractWindowedCursor {
4850
private int mCursorWindowCapacity;
4951

5052
/** A mapping of column names to column indices, to speed up lookups */
51-
private SparseIntArray mColumnNameMap;
53+
private SparseIntArray mColumnNameArray;
54+
private HashMap<String, Integer> mColumnNameMap;
5255

5356
/** Used to find out where a cursor was allocated in case it never got released. */
5457
private final CloseGuard mCloseGuard;
@@ -70,7 +73,6 @@ public SQLiteCursor(SQLiteCursorDriver driver, String editTable, SQLiteQuery que
7073
throw new IllegalArgumentException("query object cannot be null");
7174
}
7275
mDriver = driver;
73-
mColumnNameMap = null;
7476
mQuery = query;
7577
mCloseGuard = CloseGuard.get();
7678
mColumns = query.getColumnNames();
@@ -137,14 +139,29 @@ private void fillWindow(int requiredPos) {
137139
@Override
138140
public int getColumnIndex(String columnName) {
139141
// Create mColumnNameMap on demand
140-
if (mColumnNameMap == null) {
142+
if (mColumnNameArray == null && mColumnNameMap == null) {
141143
String[] columns = mColumns;
142144
int columnCount = columns.length;
143145
SparseIntArray map = new SparseIntArray(columnCount);
146+
boolean collision = false;
144147
for (int i = 0; i < columnCount; i++) {
145-
map.put(columns[i].hashCode(), i);
148+
int key = columns[i].hashCode();
149+
// check for hashCode collision
150+
if (map.get(key, -1) != -1) {
151+
collision = true;
152+
break;
153+
}
154+
map.put(key, i);
155+
}
156+
157+
if (collision) {
158+
mColumnNameMap = new HashMap<>();
159+
for (int i = 0; i < columnCount; i++) {
160+
mColumnNameMap.put(columns[i], i);
161+
}
162+
} else {
163+
mColumnNameArray = map;
146164
}
147-
mColumnNameMap = map;
148165
}
149166

150167
// Hack according to bug 903852
@@ -155,7 +172,12 @@ public int getColumnIndex(String columnName) {
155172
columnName = columnName.substring(periodIndex + 1);
156173
}
157174

158-
return mColumnNameMap.get(columnName.hashCode(), -1);
175+
if (mColumnNameMap != null) {
176+
Integer i = mColumnNameMap.get(columnName);
177+
return i == null ? -1 : i;
178+
} else {
179+
return mColumnNameArray.get(columnName.hashCode(), -1);
180+
}
159181
}
160182

161183
@Override

0 commit comments

Comments
 (0)