ngageoint / geopackage-android

GeoPackage Android Library
http://ngageoint.github.io/geopackage-android
MIT License
94 stars 32 forks source link

suport cache result #51

Closed sunshine0576 closed 5 years ago

sunshine0576 commented 5 years ago

When large data is frequently queried, the speed of building data is too slow. For data over 1W, index queries take only a few milliseconds, and building FeatureRow takes more than 3-5 seconds. In most cases, only a small part of the data will be updated during map movement. Supporting caching when querying can greatly improve the speed of map loading.


public class FeatureIndexRTreeResults implements FeatureIndexResults {
  public FeatureIndexRTreeResults(RTreeIndexTableDao dao,
                                    UserCustomCursor cursor) {
        this.dao = dao;
        this.cursor = cursor;
        String tableName=dao.getFeatureDao().getTableName();
        this.lruCache= CacheManager.getCache(tableName);
    }
@Override
            public FeatureRow next() {
                Long id=dao.getRow(cursor).getId();
                Object obj=lruCache.get(id);
                if(obj!=null){
                    Log.d("lruCache", "cacheID:"+id );
                    return (FeatureRow) obj;
                }
                FeatureRow row=dao.getFeatureRow(cursor);
                lruCache.put(id,row);
                Log.d("next", "nextID: "+id );
                return row;
            }
}
public class CacheManager {
    static Map<String,LruCache> cacheMap=new HashMap<>();
    public static int MaxSize=1000;
    public static LruCache getCache(String tableName) {
        if(cacheMap.containsKey(tableName)){
            return cacheMap.get(tableName);
        }else {
            LruCache cache= new LruCache(MaxSize);
            cacheMap.put(tableName,cache);
            return cache;
        }
    }
}
bosborn commented 5 years ago

I wouldn't want to force caching for all query situations. Instead, I added the ability to iterate through the ids without creating the feature rows (for certain result types including RTree). Added some cache classes that you can use to maintain the rows within a single table and the rows for all tables in a single GeoPackage.

Example:

FeatureCacheTables featureCache = new FeatureCacheTables();

List<String> featureTables = geoPackage.getFeatureTables();
for (String featureTable : featureTables) {

    FeatureDao featureDao = geoPackage.getFeatureDao(featureTable);
    FeatureIndexManager featureIndexManager = new FeatureIndexManager(activity,
            geoPackage, featureDao);

    for(int i = 0; i < 2; i++) {

        FeatureIndexResults featureIndexResults = featureIndexManager.query();
        for (long featureRowId : featureIndexResults.ids()) {

            FeatureRow featureRow = featureCache.get(featureTable, featureRowId);
            if (featureRow == null) {
                featureRow = featureDao.queryForIdRow(featureRowId);
                featureCache.put(featureRow);
            }
        }
        featureIndexResults.close();
    }

    featureIndexManager.close();
}