class PartitionDataStorage implements AutoCloseable {

    <D> D computeDataIfAbsent(int part, Supplier<D> supplier) {
        ObjectWithUsageStat objWithStat = storage.get(part);

        if (objWithStat == null) {
            Lock lock = locks.computeIfAbsent(part, p -> new ReentrantLock());

            lock.lock();
            try {
                objWithStat = storage.get(part);
                if (objWithStat == null) {
                    objWithStat = new ObjectWithUsageStat(supplier.get());
                    storage.put(part, objWithStat);
                    if (ttl > -1)
                        executor.schedule(new Cleaner(part), ttl, TimeUnit.MILLISECONDS);
                }
            }
            finally {
                lock.unlock();
            }
        }

        objWithStat.updateLastAccessTime();

        return (D)objWithStat.data;
    }

    public  PartitionDataStorage(long ttl);

}