Skip to content

Commit d51f894

Browse files
Inherited Repositories are now realized by reading and not writing
This saves storage space
1 parent 8f59872 commit d51f894

30 files changed

Lines changed: 294 additions & 169 deletions

.run/Run Complex Demo.run.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<configuration default="false" name="Run Complex Demo" type="Application" factoryName="Application">
33
<option name="MAIN_CLASS_NAME" value="software.xdev.spring.data.eclipse.store.demo.complex.ComplexDemoApplication" />
44
<module name="spring-data-eclipse-store-demo" />
5-
<option name="VM_PARAMETERS" value="--add-opens java.base/java.util=ALL-UNNAMED" />
5+
<option name="VM_PARAMETERS" value="--add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED" />
66
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
77
<extension name="coverage">
88
<pattern>

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EntityListProvider.java renamed to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/core/EntityListProvider.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,11 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package software.xdev.spring.data.eclipse.store.repository;
17-
18-
import software.xdev.spring.data.eclipse.store.core.IdentitySet;
19-
16+
package software.xdev.spring.data.eclipse.store.core;
2017

2118
public interface EntityListProvider
2219
{
23-
<T> IdentitySet<T> getEntityList(final Class<T> clazz);
20+
<T> EntityProvider<T> getEntityProvider(final Class<T> clazz);
2421

2522
<T> long getEntityCount(final Class<T> clazz);
2623
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright © 2024 XDEV Software (https://xdev.software)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package software.xdev.spring.data.eclipse.store.core;
17+
18+
import java.util.ArrayList;
19+
import java.util.Collection;
20+
import java.util.List;
21+
import java.util.Set;
22+
import java.util.stream.Collectors;
23+
import java.util.stream.Stream;
24+
25+
26+
public class EntityProvider<T>
27+
{
28+
private final List<IdentitySet<? extends T>> identitySets = new ArrayList<>();
29+
30+
public void addIdentitySet(final IdentitySet<? extends T> identitySet)
31+
{
32+
this.identitySets.add(identitySet);
33+
}
34+
35+
public Stream<? extends T> stream()
36+
{
37+
return this.identitySets.stream().flatMap(Set::stream);
38+
}
39+
40+
public Collection<T> toCollection()
41+
{
42+
return this.stream().collect(Collectors.toUnmodifiableList());
43+
}
44+
45+
public boolean isEmpty()
46+
{
47+
return this.stream().findAny().isEmpty();
48+
}
49+
50+
public long size()
51+
{
52+
return this.stream().count();
53+
}
54+
}

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/core/IdentitySet.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.Map;
2222
import java.util.Objects;
2323
import java.util.Set;
24+
import java.util.stream.Collectors;
2425

2526
import jakarta.annotation.Nonnull;
2627

@@ -101,7 +102,8 @@ public boolean containsAll(@Nonnull final Collection<?> c)
101102
@Override
102103
public boolean addAll(@Nonnull final Collection<? extends E> c)
103104
{
104-
throw new NotImplementedYetError();
105+
this.internalMap.putAll(c.stream().collect(Collectors.toMap(e -> e, i -> true)));
106+
return true;
105107
}
106108

107109
@Override

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreStorage.java

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.slf4j.Logger;
3232
import org.slf4j.LoggerFactory;
3333

34+
import software.xdev.spring.data.eclipse.store.core.EntityListProvider;
35+
import software.xdev.spring.data.eclipse.store.core.EntityProvider;
3436
import software.xdev.spring.data.eclipse.store.core.IdentitySet;
3537
import software.xdev.spring.data.eclipse.store.exceptions.AlreadyRegisteredException;
3638
import software.xdev.spring.data.eclipse.store.repository.config.EclipseStoreClientConfiguration;
@@ -150,16 +152,21 @@ public synchronized <T> void registerEntity(
150152
}
151153
}
152154

153-
@SuppressWarnings("unchecked")
154-
@Override
155-
public <T> IdentitySet<T> getEntityList(final Class<T> clazz)
155+
private <T> IdentitySet<T> getEntityList(final Class<T> clazz)
156156
{
157157
this.ensureEntitiesInRoot();
158158
return this.readWriteLock.read(
159159
() -> this.root.getEntityList(clazz)
160160
);
161161
}
162162

163+
@Override
164+
public <T> EntityProvider<T> getEntityProvider(final Class<T> clazz)
165+
{
166+
this.ensureEntitiesInRoot();
167+
return this.entitySetCollector.getRelatedIdentitySets(clazz);
168+
}
169+
163170
@SuppressWarnings("unchecked")
164171
@Override
165172
public <T> long getEntityCount(final Class<T> clazz)
@@ -206,21 +213,15 @@ public <T> void store(
206213
*/
207214
private <T> Collection<Object> collectRootEntitiesToStore(final Class<T> clazz, final Iterable<T> entitiesToStore)
208215
{
209-
final List<IdentitySet<Object>> entityLists =
210-
this.entitySetCollector.getRelatedIdentitySets(clazz);
216+
final IdentitySet<T> identitySet = this.getEntityList(clazz);
211217
final Collection<Object> objectsToStore = new ArrayList<>();
212218
for(final T entityToStore : entitiesToStore)
213219
{
214-
entityLists.forEach(
215-
relatedIdentitySet ->
216-
{
217-
if(!relatedIdentitySet.contains(entityToStore))
218-
{
219-
relatedIdentitySet.add(entityToStore);
220-
objectsToStore.add(relatedIdentitySet.getInternalMap());
221-
}
222-
}
223-
);
220+
if(!identitySet.contains(entityToStore))
221+
{
222+
identitySet.add(entityToStore);
223+
objectsToStore.add(identitySet.getInternalMap());
224+
}
224225
objectsToStore.add(entityToStore);
225226
// Add the separate lists of entities to store.
226227
this.repositorySynchronizer.syncAndReturnChangedObjectLists(entityToStore).forEach(
@@ -236,13 +237,9 @@ public <T> void delete(final Class<T> clazz, final T objectToRemove)
236237
this.readWriteLock.write(
237238
() ->
238239
{
239-
final List<IdentitySet<Object>> entityLists =
240-
this.entitySetCollector.getRelatedIdentitySets(clazz);
241-
entityLists.forEach(entityList ->
242-
{
243-
entityList.remove(objectToRemove);
244-
this.storageManager.store(entityList.getInternalMap());
245-
});
240+
final IdentitySet<T> entityList = this.getEntityList(clazz);
241+
entityList.remove(objectToRemove);
242+
this.storageManager.store(entityList.getInternalMap());
246243
if(LOG.isDebugEnabled())
247244
{
248245
LOG.debug("Deleted single entity of class {}.", clazz.getSimpleName());
@@ -257,16 +254,11 @@ public <T> void deleteAll(final Class<T> clazz)
257254
this.readWriteLock.write(
258255
() ->
259256
{
260-
final IdentitySet<T> entities = this.root.getEntityList(clazz);
257+
final IdentitySet<T> entities = this.getEntityList(clazz);
261258
final int oldSize = entities.size();
262259
final List<T> entitiesToRemove = entities.stream().toList();
263-
final List<IdentitySet<Object>> entityLists =
264-
this.entitySetCollector.getRelatedIdentitySets(clazz);
265-
entityLists.forEach(entityList ->
266-
{
267-
entityList.removeAll(entitiesToRemove);
268-
this.storageManager.store(entityList.getInternalMap());
269-
});
260+
entities.removeAll(entitiesToRemove);
261+
this.storageManager.store(entities.getInternalMap());
270262
if(LOG.isDebugEnabled())
271263
{
272264
LOG.debug("Deleted {} entities of class {}.", oldSize, clazz.getSimpleName());

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EntitySetCollector.java

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,33 +15,32 @@
1515
*/
1616
package software.xdev.spring.data.eclipse.store.repository;
1717

18-
import java.util.ArrayList;
1918
import java.util.HashMap;
20-
import java.util.List;
2119
import java.util.Map;
2220
import java.util.Set;
2321
import java.util.function.Function;
2422

2523
import org.slf4j.Logger;
2624
import org.slf4j.LoggerFactory;
2725

26+
import software.xdev.spring.data.eclipse.store.core.EntityProvider;
2827
import software.xdev.spring.data.eclipse.store.core.IdentitySet;
2928

3029

3130
public class EntitySetCollector
3231
{
3332
private static final Logger LOG = LoggerFactory.getLogger(EntitySetCollector.class);
34-
private final Map<Class<?>, List<IdentitySet<? super Object>>> childClassToParentSets = new HashMap<>();
33+
private final Map<Class<?>, EntityProvider<?>> childClassToParentSets = new HashMap<>();
3534

36-
public EntitySetCollector(
37-
final Function<Class<?>, IdentitySet<?>> entityLists,
35+
public <T> EntitySetCollector(
36+
final Function<Class<T>, IdentitySet<T>> entityLists,
3837
final Set<Class<?>> entityClasses)
3938
{
4039
this.buildParentClassList(entityLists, entityClasses);
4140
}
4241

43-
private void buildParentClassList(
44-
final Function<Class<?>, IdentitySet<?>> entityLists,
42+
private <T> void buildParentClassList(
43+
final Function<Class<T>, IdentitySet<T>> entityLists,
4544
final Set<Class<?>> entityClasses
4645
)
4746
{
@@ -54,12 +53,15 @@ private void buildParentClassList(
5453
for(final Class<?> possibleChildEntry : entityClasses)
5554
{
5655
this.childClassToParentSets.putIfAbsent(
57-
possibleChildEntry, new ArrayList<>()
56+
possibleChildEntry, new EntityProvider<>()
5857
);
59-
if(possibleParentEntry.isAssignableFrom(possibleChildEntry))
58+
if(possibleChildEntry.isAssignableFrom(possibleParentEntry))
6059
{
61-
this.childClassToParentSets.get(possibleChildEntry)
62-
.add((IdentitySet<? super Object>)entityLists.apply(possibleParentEntry));
60+
this.addIdentitySet(
61+
(EntityProvider<T>)this.childClassToParentSets.get(possibleChildEntry),
62+
entityLists,
63+
(Class<T>)possibleParentEntry
64+
);
6365
}
6466
}
6567
}
@@ -69,11 +71,20 @@ private void buildParentClassList(
6971
}
7072
}
7173

74+
private <T> void addIdentitySet(
75+
final EntityProvider<T> entities,
76+
final Function<Class<T>, IdentitySet<T>> entityLists,
77+
final Class<T> possibleParentEntry
78+
)
79+
{
80+
entities.addIdentitySet(entityLists.apply(possibleParentEntry));
81+
}
82+
7283
/**
7384
* @return a list with all related IdentitySets (including its own).
7485
*/
75-
public <T> List<IdentitySet<Object>> getRelatedIdentitySets(final Class<T> clazz)
86+
public <T> EntityProvider<T> getRelatedIdentitySets(final Class<T> clazz)
7687
{
77-
return this.childClassToParentSets.get(clazz);
88+
return (EntityProvider<T>)this.childClassToParentSets.get(clazz);
7889
}
7990
}

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/FindAllEclipseStoreQueryProvider.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717

1818
import java.lang.reflect.Method;
1919

20+
import jakarta.annotation.Nonnull;
21+
2022
import org.springframework.data.repository.query.QueryMethod;
2123
import org.springframework.data.repository.query.RepositoryQuery;
2224
import org.springframework.data.util.TypeInformation;
2325

24-
import jakarta.annotation.Nonnull;
25-
import software.xdev.spring.data.eclipse.store.repository.EntityListProvider;
26+
import software.xdev.spring.data.eclipse.store.core.EntityListProvider;
2627
import software.xdev.spring.data.eclipse.store.repository.Query;
2728
import software.xdev.spring.data.eclipse.store.repository.query.criteria.Criteria;
2829
import software.xdev.spring.data.eclipse.store.repository.query.executors.QueryExecutor;
@@ -78,7 +79,7 @@ public Object execute(@Nonnull final Object[] values)
7879
return
7980
QueryExecutorCreator
8081
.createQuery(this.typeInformation, this.copier, Criteria.createNoCriteria(), null)
81-
.execute(this.domainClass, this.entityListProvider.getEntityList(this.domainClass), values);
82+
.execute(this.domainClass, this.entityListProvider.getEntityProvider(this.domainClass), values);
8283
}
8384

8485
@Override

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/StringBasedEclipseStoreQueryProvider.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import java.lang.reflect.Method;
1919
import java.util.Objects;
2020

21+
import jakarta.annotation.Nonnull;
22+
2123
import org.slf4j.Logger;
2224
import org.slf4j.LoggerFactory;
2325
import org.springframework.data.repository.query.Parameters;
@@ -27,8 +29,7 @@
2729
import org.springframework.data.repository.query.parser.PartTree;
2830
import org.springframework.data.util.TypeInformation;
2931

30-
import jakarta.annotation.Nonnull;
31-
import software.xdev.spring.data.eclipse.store.repository.EntityListProvider;
32+
import software.xdev.spring.data.eclipse.store.core.EntityListProvider;
3233
import software.xdev.spring.data.eclipse.store.repository.query.executors.QueryExecutor;
3334
import software.xdev.spring.data.eclipse.store.repository.support.copier.working.WorkingCopier;
3435

@@ -90,7 +91,7 @@ public Object execute(@Nonnull final Object[] values)
9091
LOG.debug("Executing query {}...", this.queryMethod);
9192
}
9293
final Object result = creator.createQuery()
93-
.execute(this.domainClass, this.entityListProvider.getEntityList(this.domainClass), values);
94+
.execute(this.domainClass, this.entityListProvider.getEntityProvider(this.domainClass), values);
9495
if(LOG.isDebugEnabled())
9596
{
9697
LOG.debug("Done executing query {}.", this.queryMethod);

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/by/example/EclipseStoreFetchableFluentQuery.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public S firstValue()
100100
() ->
101101
(S)query.execute(
102102
this.domainClass,
103-
this.storage.getEntityList(this.domainClass),
103+
this.storage.getEntityProvider(this.domainClass),
104104
new Object[]{this.sort})
105105
);
106106
}
@@ -111,7 +111,10 @@ public List<S> all()
111111
final ListQueryExecutor<T> query =
112112
new ListQueryExecutor<>(this.copier, new CriteriaByExample<>(this.example));
113113
return this.storage.getReadWriteLock().read(
114-
() -> (List<S>)query.execute(this.domainClass, this.storage.getEntityList(this.domainClass), new Object[]{
114+
() -> (List<S>)query.execute(
115+
this.domainClass,
116+
this.storage.getEntityProvider(this.domainClass),
117+
new Object[]{
115118
this.sort})
116119
);
117120
}
@@ -125,7 +128,7 @@ public Page<S> page(final Pageable pageable)
125128
() ->
126129
(Page<S>)pageableQuery.execute(
127130
this.domainClass,
128-
this.storage.getEntityList(this.domainClass),
131+
this.storage.getEntityProvider(this.domainClass),
129132
new Object[]{pageable, this.sort})
130133
);
131134
}
@@ -141,7 +144,7 @@ public long count()
141144
{
142145
final CountQueryExecutor<T> query = new CountQueryExecutor<>(new CriteriaByExample<>(this.example));
143146
return this.storage.getReadWriteLock().read(
144-
() -> query.execute(this.domainClass, this.storage.getEntityList(this.domainClass), null)
147+
() -> query.execute(this.domainClass, this.storage.getEntityProvider(this.domainClass), null)
145148
);
146149
}
147150

@@ -150,7 +153,7 @@ public boolean exists()
150153
{
151154
final ExistsQueryExecutor<T> query = new ExistsQueryExecutor<>(new CriteriaByExample<>(this.example));
152155
return this.storage.getReadWriteLock().read(
153-
() -> query.execute(this.domainClass, this.storage.getEntityList(this.domainClass), null)
156+
() -> query.execute(this.domainClass, this.storage.getEntityProvider(this.domainClass), null)
154157
);
155158
}
156159
}

0 commit comments

Comments
 (0)