view flys-backend/src/main/java/de/intevation/flys/importer/ImporterSession.java @ 501:04d449f7f0c9

Importer: Change caching strategy not to cause OOM any more. flys-backend/trunk@1855 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 09 May 2011 00:15:45 +0000
parents d50cd3a632e0
children c6889097f81f
line wrap: on
line source
package de.intevation.flys.importer;

import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
import java.util.LinkedHashMap;

import java.math.BigDecimal;

import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.hibernate.Query;
import org.hibernate.FlushMode;

import de.intevation.flys.backend.SessionFactoryProvider;

import de.intevation.flys.model.WstColumnValue;
import de.intevation.flys.model.WstColumn;
import de.intevation.flys.model.DischargeTableValue;
import de.intevation.flys.model.DischargeTable;
import de.intevation.flys.model.Range;
import de.intevation.flys.model.River;

import org.apache.log4j.Logger;

public class ImporterSession
{
    private static Logger log = Logger.getLogger(ImporterSession.class);

    public static final int MAX_WST_CACHE_SIZE = 20;
    public static final int MAX_AT_CACHE_SIZE  = 20;

    private static final ThreadLocal<ImporterSession> SESSION =
        new ThreadLocal<ImporterSession>() {
            @Override
            protected ImporterSession initialValue() {
                return new ImporterSession();
            }
        };

    protected Session databaseSession;

    protected Map<Integer, Map<ValueKey, WstColumnValue>> wstColumnValues;

    protected Map<Integer, Map<ValueKey, DischargeTableValue>>
        dischargeTableValues;

    protected Map<IdValueKey, Range> ranges;

    public static ImporterSession getInstance() {
        return SESSION.get();
    }

    public ImporterSession() {
        SessionFactory sessionFactory =
            SessionFactoryProvider.createSessionFactory();
        databaseSession = sessionFactory.openSession();
        databaseSession.setFlushMode(FlushMode.MANUAL);

        wstColumnValues =
            new LinkedHashMap<Integer, Map<ValueKey, WstColumnValue>>() {
                @Override
                protected boolean removeEldestEntry(
                    Map.Entry<Integer, Map<ValueKey, WstColumnValue>> eldest
                ) {
                    return size() > MAX_WST_CACHE_SIZE;
                }
            };

        dischargeTableValues =
            new LinkedHashMap<Integer, Map<ValueKey, DischargeTableValue>>() {
                @Override
                protected boolean removeEldestEntry(
                    Map.Entry<Integer, Map<ValueKey, DischargeTableValue>> eldest
                ) {
                    return size() > MAX_AT_CACHE_SIZE;
                }
            };
    }

    public Session getDatabaseSession() {
        return databaseSession;
    }

    public WstColumnValue getWstColumnValue(
        WstColumn  column,
        BigDecimal position,
        BigDecimal w
    ) {
        Integer c = column.getId();

        Map<ValueKey, WstColumnValue> map = wstColumnValues.get(c);

        if (map == null) {
            map = new HashMap<ValueKey, WstColumnValue>();
            wstColumnValues.put(c, map);
            Query query = databaseSession.createQuery(
                "from WstColumnValue where wstColumn.id=:cid");
            query.setParameter("cid", c);
            for (Iterator iter = query.iterate(); iter.hasNext();) {
                WstColumnValue wcv = (WstColumnValue)iter.next();
                map.put(new ValueKey(wcv.getPosition(), wcv.getW()), wcv);
            }
        }

        ValueKey key = new ValueKey(position, w);

        WstColumnValue wcv = map.get(key);

        if (wcv != null) {
            return wcv;
        }

        wcv = new WstColumnValue(column, position, w);

        databaseSession.save(wcv);

        map.put(key, wcv);

        return wcv;
    }

    public DischargeTableValue getDischargeTableValue(
        DischargeTable table,
        BigDecimal     q,
        BigDecimal     w
    ) {
        Integer t = table.getId();

        Map<ValueKey, DischargeTableValue> map =
            dischargeTableValues.get(t);

        if (map == null) {
            map = new HashMap<ValueKey, DischargeTableValue>();
            dischargeTableValues.put(t, map);
            Query query = databaseSession.createQuery(
                "from DischargeTableValue where dischargeTable.id=:tid");
            query.setParameter("tid", t);
            for (Iterator iter = query.iterate(); iter.hasNext();) {
                DischargeTableValue dctv = (DischargeTableValue)iter.next();
                map.put(new ValueKey(q, w), dctv);
            }
        }

        ValueKey key = new ValueKey(q, w);

        DischargeTableValue dctv = map.get(key);

        if (dctv != null) {
            return dctv;
        }

        dctv = new DischargeTableValue(table, q, w);

        databaseSession.save(dctv);

        map.put(key, dctv);

        return dctv;
    }

    public Range getRange(River river, BigDecimal a, BigDecimal b) {

        if (ranges == null) {
            loadRanges();
        }

        IdValueKey key = new IdValueKey(river.getId(), a, b);

        Range range = ranges.get(key);

        if (ranges != null) {
            return range;
        }

        range = new Range(a, b, river);

        databaseSession.save(range);

        ranges.put(key, range);

        return range;
    }

    protected void loadRanges() {
        log.info("load ranges");
        ranges = new HashMap<IdValueKey, Range>();

        Query query = databaseSession.createQuery("from Range");

        for (Iterator iter = query.iterate(); iter.hasNext();) {
            Range range = (Range)iter.next();
            ranges.put(new IdValueKey(range), range);
        }
        log.info(ranges.size() + " values loaded");
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org