/** * Copyright (c) 2015 The original author or authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.reveno.atp.core.engine.components; import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; import org.reveno.atp.api.domain.RepositoryData; import org.reveno.atp.api.domain.WriteableRepository; import java.util.Map; import java.util.Set; /** * Used for recording which entities were modified on stage of Transaction execution, since * we will want that info on next step where we updating Views mappings. * * @author Artem Dmitriev <art.dm.ser@gmail.com> * */ public class RecordingRepository implements WriteableRepository { private WriteableRepository underlyingRepo; public RecordingRepository underlying(WriteableRepository repository) { this.underlyingRepo = repository; return this; } public RecordingRepository enableReadMark() { this.readMarking = true; return this; } public RecordingRepository disableReadMark() { this.readMarking = false; return this; } public RecordingRepository map(Map<Class<?>, Long2ObjectLinkedOpenHashMap<Object>> markedRecords) { this.markedRecords = markedRecords; return this; } @Override public <T> T get(Class<T> entityType, long id) { T result = underlyingRepo.get(entityType, id); if (result != null && readMarking) markedRecords.get(entityType).put(id, result); return result; } @Override public <T> boolean has(Class<T> entityType, long id) { return underlyingRepo.has(entityType, id); } @Override public <T> T getClean(Class<T> entityType, long id) { return underlyingRepo.getClean(entityType, id); } @Override public RepositoryData getData() { RepositoryData data = underlyingRepo.getData(); if (readMarking) { data.data.forEach((k, v) -> markedRecords.get(k).putAll(v)); } return data; } @Override public Map<Long, Object> getEntities(Class<?> entityType) { Map<Long, Object> result = underlyingRepo.getEntities(entityType); if (readMarking) { markedRecords.get(entityType).putAll(result); } return result; } @Override public Map<Long, Object> getEntitiesClean(Class<?> entityType) { return underlyingRepo.getEntitiesClean(entityType); } @Override public <T> T store(long entityId, T entity) { markedRecords.get(entity.getClass()).put(entityId, entity); return underlyingRepo.store(entityId, entity); } @Override public <T> T store(long entityId, Class<? super T> type, T entity) { markedRecords.get(type).put(entityId, entity); return underlyingRepo.store(entityId, type, entity); } @Override public <T> T remove(Class<T> entityClass, long entityId) { markedRecords.get(entityClass).remove(entityId); markedRecords.get(entityClass).put(-entityId, EMPTY); return underlyingRepo.remove(entityClass, entityId); } @Override public void load(Map<Class<?>, Map<Long, Object>> map) { underlyingRepo.load(map); } @Override public Set<Class<?>> getEntityTypes() { return underlyingRepo.getEntityTypes(); } protected Map<Class<?>, Long2ObjectLinkedOpenHashMap<Object>> markedRecords; protected boolean readMarking = true; protected static final Object EMPTY = new Object(); }