Skip to content

Commit 0685958

Browse files
Merge pull request greenrobot#236 from greenrobot-team/indexed-entity-test
Add indexed property performance tests.
2 parents 25908b4 + b8968e8 commit 0685958

File tree

35 files changed

+1262
-220
lines changed

35 files changed

+1262
-220
lines changed

DaoTest/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ apply plugin: 'com.android.application'
1212

1313
dependencies {
1414
androidTestCompile project(':DaoCore')
15+
androidTestCompile project(':PerformanceTests:Common')
1516

1617
testCompile project(':DaoCore')
1718
testCompile 'org.robolectric:robolectric:3.0'

DaoTest/src-gen/de/greenrobot/daotest/DaoMaster.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import de.greenrobot.daotest.AutoincrementEntityDao;
2626
import de.greenrobot.daotest.SqliteMasterDao;
2727
import de.greenrobot.daotest.CustomTypeEntityDao;
28+
import de.greenrobot.daotest.IndexedStringEntityDao;
2829

2930
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
3031
/**
@@ -51,6 +52,7 @@ public static void createAllTables(SQLiteDatabase db, boolean ifNotExists) {
5152
StringKeyValueEntityDao.createTable(db, ifNotExists);
5253
AutoincrementEntityDao.createTable(db, ifNotExists);
5354
CustomTypeEntityDao.createTable(db, ifNotExists);
55+
IndexedStringEntityDao.createTable(db, ifNotExists);
5456
}
5557

5658
/** Drops underlying database table using DAOs. */
@@ -71,6 +73,7 @@ public static void dropAllTables(SQLiteDatabase db, boolean ifExists) {
7173
StringKeyValueEntityDao.dropTable(db, ifExists);
7274
AutoincrementEntityDao.dropTable(db, ifExists);
7375
CustomTypeEntityDao.dropTable(db, ifExists);
76+
IndexedStringEntityDao.dropTable(db, ifExists);
7477
}
7578

7679
public static abstract class OpenHelper extends SQLiteOpenHelper {
@@ -119,6 +122,7 @@ public DaoMaster(SQLiteDatabase db) {
119122
registerDaoClass(AutoincrementEntityDao.class);
120123
registerDaoClass(SqliteMasterDao.class);
121124
registerDaoClass(CustomTypeEntityDao.class);
125+
registerDaoClass(IndexedStringEntityDao.class);
122126
}
123127

124128
public DaoSession newSession() {

DaoTest/src-gen/de/greenrobot/daotest/DaoSession.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import de.greenrobot.daotest.AutoincrementEntity;
2727
import de.greenrobot.daotest.SqliteMaster;
2828
import de.greenrobot.daotest.CustomTypeEntity;
29+
import de.greenrobot.daotest.IndexedStringEntity;
2930

3031
import de.greenrobot.daotest.SimpleEntityDao;
3132
import de.greenrobot.daotest.SimpleEntityNotNullDao;
@@ -44,6 +45,7 @@
4445
import de.greenrobot.daotest.AutoincrementEntityDao;
4546
import de.greenrobot.daotest.SqliteMasterDao;
4647
import de.greenrobot.daotest.CustomTypeEntityDao;
48+
import de.greenrobot.daotest.IndexedStringEntityDao;
4749

4850
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
4951

@@ -71,6 +73,7 @@ public class DaoSession extends AbstractDaoSession {
7173
private final DaoConfig autoincrementEntityDaoConfig;
7274
private final DaoConfig sqliteMasterDaoConfig;
7375
private final DaoConfig customTypeEntityDaoConfig;
76+
private final DaoConfig indexedStringEntityDaoConfig;
7477

7578
private final SimpleEntityDao simpleEntityDao;
7679
private final SimpleEntityNotNullDao simpleEntityNotNullDao;
@@ -89,6 +92,7 @@ public class DaoSession extends AbstractDaoSession {
8992
private final AutoincrementEntityDao autoincrementEntityDao;
9093
private final SqliteMasterDao sqliteMasterDao;
9194
private final CustomTypeEntityDao customTypeEntityDao;
95+
private final IndexedStringEntityDao indexedStringEntityDao;
9296

9397
public DaoSession(SQLiteDatabase db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>
9498
daoConfigMap) {
@@ -145,6 +149,9 @@ public DaoSession(SQLiteDatabase db, IdentityScopeType type, Map<Class<? extends
145149
customTypeEntityDaoConfig = daoConfigMap.get(CustomTypeEntityDao.class).clone();
146150
customTypeEntityDaoConfig.initIdentityScope(type);
147151

152+
indexedStringEntityDaoConfig = daoConfigMap.get(IndexedStringEntityDao.class).clone();
153+
indexedStringEntityDaoConfig.initIdentityScope(type);
154+
148155
simpleEntityDao = new SimpleEntityDao(simpleEntityDaoConfig, this);
149156
simpleEntityNotNullDao = new SimpleEntityNotNullDao(simpleEntityNotNullDaoConfig, this);
150157
testEntityDao = new TestEntityDao(testEntityDaoConfig, this);
@@ -162,6 +169,7 @@ public DaoSession(SQLiteDatabase db, IdentityScopeType type, Map<Class<? extends
162169
autoincrementEntityDao = new AutoincrementEntityDao(autoincrementEntityDaoConfig, this);
163170
sqliteMasterDao = new SqliteMasterDao(sqliteMasterDaoConfig, this);
164171
customTypeEntityDao = new CustomTypeEntityDao(customTypeEntityDaoConfig, this);
172+
indexedStringEntityDao = new IndexedStringEntityDao(indexedStringEntityDaoConfig, this);
165173

166174
registerDao(SimpleEntity.class, simpleEntityDao);
167175
registerDao(SimpleEntityNotNull.class, simpleEntityNotNullDao);
@@ -180,6 +188,7 @@ public DaoSession(SQLiteDatabase db, IdentityScopeType type, Map<Class<? extends
180188
registerDao(AutoincrementEntity.class, autoincrementEntityDao);
181189
registerDao(SqliteMaster.class, sqliteMasterDao);
182190
registerDao(CustomTypeEntity.class, customTypeEntityDao);
191+
registerDao(IndexedStringEntity.class, indexedStringEntityDao);
183192
}
184193

185194
public void clear() {
@@ -200,6 +209,7 @@ public void clear() {
200209
autoincrementEntityDaoConfig.getIdentityScope().clear();
201210
sqliteMasterDaoConfig.getIdentityScope().clear();
202211
customTypeEntityDaoConfig.getIdentityScope().clear();
212+
indexedStringEntityDaoConfig.getIdentityScope().clear();
203213
}
204214

205215
public SimpleEntityDao getSimpleEntityDao() {
@@ -270,4 +280,8 @@ public CustomTypeEntityDao getCustomTypeEntityDao() {
270280
return customTypeEntityDao;
271281
}
272282

283+
public IndexedStringEntityDao getIndexedStringEntityDao() {
284+
return indexedStringEntityDao;
285+
}
286+
273287
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package de.greenrobot.daotest;
2+
3+
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable "keep" sections if you want to edit.
4+
/**
5+
* Entity mapped to table "INDEXED_STRING_ENTITY".
6+
*/
7+
public class IndexedStringEntity {
8+
9+
private Long id;
10+
private String indexedString;
11+
12+
public IndexedStringEntity() {
13+
}
14+
15+
public IndexedStringEntity(Long id) {
16+
this.id = id;
17+
}
18+
19+
public IndexedStringEntity(Long id, String indexedString) {
20+
this.id = id;
21+
this.indexedString = indexedString;
22+
}
23+
24+
public Long getId() {
25+
return id;
26+
}
27+
28+
public void setId(Long id) {
29+
this.id = id;
30+
}
31+
32+
public String getIndexedString() {
33+
return indexedString;
34+
}
35+
36+
public void setIndexedString(String indexedString) {
37+
this.indexedString = indexedString;
38+
}
39+
40+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package de.greenrobot.daotest;
2+
3+
import android.database.Cursor;
4+
import android.database.sqlite.SQLiteDatabase;
5+
import android.database.sqlite.SQLiteStatement;
6+
7+
import de.greenrobot.dao.AbstractDao;
8+
import de.greenrobot.dao.Property;
9+
import de.greenrobot.dao.internal.DaoConfig;
10+
11+
import de.greenrobot.daotest.IndexedStringEntity;
12+
13+
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
14+
/**
15+
* DAO for table "INDEXED_STRING_ENTITY".
16+
*/
17+
public class IndexedStringEntityDao extends AbstractDao<IndexedStringEntity, Long> {
18+
19+
public static final String TABLENAME = "INDEXED_STRING_ENTITY";
20+
21+
/**
22+
* Properties of entity IndexedStringEntity.<br/>
23+
* Can be used for QueryBuilder and for referencing column names.
24+
*/
25+
public static class Properties {
26+
public final static Property Id = new Property(0, Long.class, "id", true, "_id");
27+
public final static Property IndexedString = new Property(1, String.class, "indexedString", false, "INDEXED_STRING");
28+
};
29+
30+
31+
public IndexedStringEntityDao(DaoConfig config) {
32+
super(config);
33+
}
34+
35+
public IndexedStringEntityDao(DaoConfig config, DaoSession daoSession) {
36+
super(config, daoSession);
37+
}
38+
39+
/** Creates the underlying database table. */
40+
public static void createTable(SQLiteDatabase db, boolean ifNotExists) {
41+
String constraint = ifNotExists? "IF NOT EXISTS ": "";
42+
db.execSQL("CREATE TABLE " + constraint + "\"INDEXED_STRING_ENTITY\" (" + //
43+
"\"_id\" INTEGER PRIMARY KEY ," + // 0: id
44+
"\"INDEXED_STRING\" TEXT);"); // 1: indexedString
45+
// Add Indexes
46+
db.execSQL("CREATE INDEX " + constraint + "IDX_INDEXED_STRING_ENTITY_INDEXED_STRING ON INDEXED_STRING_ENTITY" +
47+
" (\"INDEXED_STRING\");");
48+
}
49+
50+
/** Drops the underlying database table. */
51+
public static void dropTable(SQLiteDatabase db, boolean ifExists) {
52+
String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"INDEXED_STRING_ENTITY\"";
53+
db.execSQL(sql);
54+
}
55+
56+
/** @inheritdoc */
57+
@Override
58+
protected void bindValues(SQLiteStatement stmt, IndexedStringEntity entity) {
59+
stmt.clearBindings();
60+
61+
Long id = entity.getId();
62+
if (id != null) {
63+
stmt.bindLong(1, id);
64+
}
65+
66+
String indexedString = entity.getIndexedString();
67+
if (indexedString != null) {
68+
stmt.bindString(2, indexedString);
69+
}
70+
}
71+
72+
/** @inheritdoc */
73+
@Override
74+
public Long readKey(Cursor cursor, int offset) {
75+
return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);
76+
}
77+
78+
/** @inheritdoc */
79+
@Override
80+
public IndexedStringEntity readEntity(Cursor cursor, int offset) {
81+
IndexedStringEntity entity = new IndexedStringEntity( //
82+
cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id
83+
cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1) // indexedString
84+
);
85+
return entity;
86+
}
87+
88+
/** @inheritdoc */
89+
@Override
90+
public void readEntity(Cursor cursor, IndexedStringEntity entity, int offset) {
91+
entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));
92+
entity.setIndexedString(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));
93+
}
94+
95+
/** @inheritdoc */
96+
@Override
97+
protected Long updateKeyAfterInsert(IndexedStringEntity entity, long rowId) {
98+
entity.setId(rowId);
99+
return rowId;
100+
}
101+
102+
/** @inheritdoc */
103+
@Override
104+
public Long getKey(IndexedStringEntity entity) {
105+
if(entity != null) {
106+
return entity.getId();
107+
} else {
108+
return null;
109+
}
110+
}
111+
112+
/** @inheritdoc */
113+
@Override
114+
protected boolean isEntityUpdateable() {
115+
return true;
116+
}
117+
118+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package de.greenrobot.daotest.entity;
2+
3+
import de.greenrobot.dao.test.AbstractDaoTestLongPk;
4+
5+
import de.greenrobot.daotest.IndexedStringEntity;
6+
import de.greenrobot.daotest.IndexedStringEntityDao;
7+
8+
public class IndexedStringEntityTest extends AbstractDaoTestLongPk<IndexedStringEntityDao, IndexedStringEntity> {
9+
10+
public IndexedStringEntityTest() {
11+
super(IndexedStringEntityDao.class);
12+
}
13+
14+
@Override
15+
protected IndexedStringEntity createEntity(Long key) {
16+
IndexedStringEntity entity = new IndexedStringEntity();
17+
entity.setId(key);
18+
return entity;
19+
}
20+
21+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package de.greenrobot.daotest.performance;
2+
3+
import de.greenrobot.dao.DaoLog;
4+
import de.greenrobot.dao.test.AbstractDaoTest;
5+
import de.greenrobot.daotest.IndexedStringEntity;
6+
import de.greenrobot.daotest.IndexedStringEntityDao;
7+
import de.greenrobot.performance.StringGenerator;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
11+
/**
12+
* Stores entities with an indexed string property and measures the duration to query them by this
13+
* string. The generated strings are in a fixed random sequence. The strings to query for are also
14+
* in a fixed random sequence.
15+
*/
16+
public class IndexedStringPerformanceTest
17+
extends AbstractDaoTest<IndexedStringEntityDao, IndexedStringEntity, Long> {
18+
19+
private static final int BATCH_SIZE = 10000;
20+
private static final int QUERY_COUNT = 1000;
21+
private static final int RUNS = 8;
22+
23+
public IndexedStringPerformanceTest() {
24+
super(IndexedStringEntityDao.class, false);
25+
}
26+
27+
public void testIndexedStringEntityQuery() {
28+
// disabled for regular builds
29+
// DaoLog.d("--------Indexed Queries: Start");
30+
// for (int i = 0; i < RUNS; i++) {
31+
// DaoLog.d("----Run " + (i + 1) + " of " + RUNS);
32+
// doIndexedStringEntityQuery();
33+
// }
34+
// DaoLog.d("--------Indexed Queries: End");
35+
}
36+
37+
private void doIndexedStringEntityQuery() {
38+
// create entities
39+
List<IndexedStringEntity> entities = new ArrayList<>(BATCH_SIZE);
40+
String[] fixedRandomStrings = StringGenerator.createFixedRandomStrings(BATCH_SIZE);
41+
for (int i = 0; i < BATCH_SIZE; i++) {
42+
IndexedStringEntity entity = new IndexedStringEntity();
43+
entity.setId((long) i);
44+
entity.setIndexedString(fixedRandomStrings[i]);
45+
entities.add(entity);
46+
}
47+
DaoLog.d("Built entities.");
48+
49+
// insert entities
50+
dao.insertInTx(entities);
51+
DaoLog.d("Inserted entities.");
52+
53+
// query for entities by indexed string at random
54+
int[] randomIndices = StringGenerator.getFixedRandomIndices(QUERY_COUNT, BATCH_SIZE - 1);
55+
56+
long start = System.currentTimeMillis();
57+
for (int i = 0; i < QUERY_COUNT; i++) {
58+
int nextIndex = randomIndices[i];
59+
//noinspection unused
60+
List<IndexedStringEntity> query = dao.queryBuilder()
61+
.where(IndexedStringEntityDao.Properties.IndexedString.eq(
62+
fixedRandomStrings[nextIndex]))
63+
.list();
64+
}
65+
long time = System.currentTimeMillis() - start;
66+
DaoLog.d("Queried for " + QUERY_COUNT + " of " + BATCH_SIZE + " indexed entities in " + time
67+
+ " ms.");
68+
69+
// delete all entities
70+
dao.deleteAll();
71+
DaoLog.d("Deleted all entities.");
72+
}
73+
}

DaoTestGenerator/src/de/greenrobot/daogenerator/gentest/TestDaoGenerator.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public TestDaoGenerator() {
6060
createAutoincrement();
6161
createSqliteMaster();
6262
createCustomType();
63+
createIndexedString();
6364

6465
schema2 = createSchema2();
6566
schemaUnitTest = createSchemaUnitTest();
@@ -262,6 +263,12 @@ protected void createCustomType() {
262263
"de.greenrobot.daotest.customtype.MyTimestampConverter");
263264
}
264265

266+
protected void createIndexedString() {
267+
Entity entity = schema.addEntity("IndexedStringEntity");
268+
entity.addIdProperty();
269+
entity.addStringProperty("indexedString").index();
270+
}
271+
265272
private Schema createSchema2() {
266273
Schema schema2 = new Schema(1, "de.greenrobot.daotest2");
267274
schema2.setDefaultJavaPackageTest("de.greenrobot.daotest2.entity");

0 commit comments

Comments
 (0)