package se.kodapan.osm.sweden.ext.se.posten.postnummer; import com.sleepycat.je.Environment; import com.sleepycat.je.EnvironmentConfig; import com.sleepycat.persist.EntityStore; import com.sleepycat.persist.PrimaryIndex; import com.sleepycat.persist.StoreConfig; import se.kodapan.osm.sweden.FileUtils; import java.io.File; /** * @author kalle * @since 2013-01-02 01:05 */ public class CachedPostenPostnummerService extends PostenPostnummerService { private static final String NULL = ""; /** if false then only store results, don't look up at query time */ private boolean usingCacheForQuery = true; public CachedPostenPostnummerService() throws Exception { super(); } public CachedPostenPostnummerService(boolean usingCacheForQuery) throws Exception { this(); this.usingCacheForQuery = usingCacheForQuery; } public CachedPostenPostnummerService(File path) throws Exception { this.path = path; } @Override public PostenPostnummerServiceResponse queryStreetAddress(String streetAddress, String city) throws Exception { return queryStreetAddress(streetAddress, city, usingCacheForQuery); } public PostenPostnummerServiceResponse queryStreetAddress(String streetAddress, String city, boolean usingCacheForQuery) throws Exception { PostenPostnummerServiceStreetAddressQuery query = new PostenPostnummerServiceStreetAddressQuery(); query.setStreetAddress(streetAddress == null ? NULL : streetAddress); query.setCity(city == null ? NULL : city); if (usingCacheForQuery && streetAddressQueryCache.contains(query)) { CachedStreetAddressQueryResponse cachedResponse = streetAddressQueryCache.get(query); return cachedResponse == null ? null : cachedResponse.getResponse(); } else { PostenPostnummerServiceResponse response = super.queryStreetAddress(streetAddress, city); streetAddressQueryCache.put(new CachedStreetAddressQueryResponse(query, response)); return response; } } @Override public PostenPostnummerServiceResponse queryPostnummer(String postnummer) throws Exception { return queryPostalCode(postnummer, usingCacheForQuery); } public PostenPostnummerServiceResponse queryPostalCode(String postalCode, boolean usingCacheForQuery) throws Exception { PostenPostnummerServicePostalCodeQuery clone = new PostenPostnummerServicePostalCodeQuery(); clone.setPostalCode(postalCode); if (usingCacheForQuery && postalCodeQueryCache.contains(clone)) { CachedPostalCodeQueryResponse cachedResponse = postalCodeQueryCache.get(clone); return cachedResponse == null ? null : cachedResponse.getResponse(); } else { PostenPostnummerServiceResponse response = super.queryPostnummer(postalCode); postalCodeQueryCache.put(new CachedPostalCodeQueryResponse(clone, response)); return response; } } private File path = new File("bdb/se.posten.postnummer"); private String storeName = "posten service cache"; private Environment environment; private com.sleepycat.persist.EntityStore entityStore; private int cacheMB = 5; private boolean readOnly = false; private PrimaryIndex<PostenPostnummerServiceStreetAddressQuery, CachedStreetAddressQueryResponse> streetAddressQueryCache; private PrimaryIndex<PostenPostnummerServicePostalCodeQuery, CachedPostalCodeQueryResponse> postalCodeQueryCache; public void open() throws Exception { // InstantiatedDomainStore store = new InstantiatedDomainStore(); // entityStore = store.new EntityStore(storeName); entityStore = jeEntityStoreFactory(); streetAddressQueryCache = entityStore.getPrimaryIndex(PostenPostnummerServiceStreetAddressQuery.class, CachedStreetAddressQueryResponse.class); postalCodeQueryCache = entityStore.getPrimaryIndex(PostenPostnummerServicePostalCodeQuery.class, CachedPostalCodeQueryResponse.class); } private EntityStore jeEntityStoreFactory() throws Exception { // log.info("Opening BDB..."); readOnly = false; if (!path.exists()) { path = FileUtils.mkdirs(path); EnvironmentConfig envConfig = new EnvironmentConfig(); envConfig.setAllowCreate(true); envConfig.setTransactional(false); envConfig.setLocking(true); envConfig.setReadOnly(false); // log.info("Creating environment " + envConfig.toString()); environment = new Environment(path, envConfig); StoreConfig storeConfig = new StoreConfig(); storeConfig.setAllowCreate(true); storeConfig.setTransactional(false); storeConfig.setReadOnly(false); // log.info("Creating store '" + storeName + "' " + storeConfig.toString()); entityStore = new EntityStore(environment, storeName, storeConfig); entityStore.close(); environment.close(); // log.info("BDB has been created"); } // open EnvironmentConfig envConfig = new EnvironmentConfig(); envConfig.setAllowCreate(true); envConfig.setTransactional(false); envConfig.setLocking(false); envConfig.setReadOnly(readOnly); envConfig.setCacheSize(cacheMB * 1024 * 1024); // // log.info("Opening environment " + envConfig.toString()); environment = new Environment(path, envConfig); StoreConfig storeConfig = new StoreConfig(); storeConfig.setAllowCreate(true); storeConfig.setTransactional(false); storeConfig.setReadOnly(readOnly); // log.info("Opening store '" + storeName + "' " + storeConfig.toString()); return new EntityStore(environment, storeName, storeConfig); } public void close() throws Exception { // log.info("Closing BDB..."); if (entityStore != null) { entityStore.close(); } if (environment != null) { environment.close(); } entityStore = null; environment = null; // log.info("BDB has been closed"); } public File getPath() { return path; } public void setPath(File path) { this.path = path; } public String getStoreName() { return storeName; } public void setStoreName(String storeName) { this.storeName = storeName; } public int getCacheMB() { return cacheMB; } public void setCacheMB(int cacheMB) { this.cacheMB = cacheMB; } public boolean isReadOnly() { return readOnly; } public void setReadOnly(boolean readOnly) { this.readOnly = readOnly; } public PrimaryIndex<PostenPostnummerServiceStreetAddressQuery, CachedStreetAddressQueryResponse> getStreetAddressQueryCache() { return streetAddressQueryCache; } public void setStreetAddressQueryCache(PrimaryIndex<PostenPostnummerServiceStreetAddressQuery, CachedStreetAddressQueryResponse> streetAddressQueryCache) { this.streetAddressQueryCache = streetAddressQueryCache; } public PrimaryIndex<PostenPostnummerServicePostalCodeQuery, CachedPostalCodeQueryResponse> getPostalCodeQueryCache() { return postalCodeQueryCache; } public void setPostalCodeQueryCache(PrimaryIndex<PostenPostnummerServicePostalCodeQuery, CachedPostalCodeQueryResponse> postalCodeQueryCache) { this.postalCodeQueryCache = postalCodeQueryCache; } public EntityStore getEntityStore() { return entityStore; } public void setEntityStore(EntityStore entityStore) { this.entityStore = entityStore; } public Environment getEnvironment() { return environment; } public void setEnvironment(Environment environment) { this.environment = environment; } }