Skip to content

Conversation

mp911de
Copy link
Member

@mp911de mp911de commented Oct 2, 2025

Allow a pluggable store for keyspace storage. Also, add missing functionality.

Closes #71

Add KeySpaceStore to retrieve a Map for each keyspace allowing to use a different implementation instead of using generic Java maps. Also, allow configuring KeySpaceStore as bean.
Use RepositoryConfigurationSource for annotation lookup directly.
@mp911de mp911de added the type: enhancement A general enhancement label Oct 2, 2025
* @since 4.0
*/
@SuppressWarnings("rawtypes")
record MapKeySpaceStore(Map<String, Map<Object, Object>> store, Class<? extends Map> keySpaceMapType,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting use of record as the impl for the store. Any limitations of using record for this? Will the equals auto-implemented by record be sufficient? It may go through the entire store contents to check equality.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using records as interface implementations is a neat pattern as our API surface is limited by the interface. Clearly, Object methods are inherited and their functionality can be surfaced in various ways. We don't define a contract regarding equality and hash code but we might fill in these blanks as we see fit.

* @param store reference to the map of maps holding the keyspace data.
* @param keySpaceMapType map type to be used for each keyspace map.
* @param initialCapacity initial keyspace map capacity to optimize allocations.
* @since 4.0
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Author?

*/
public MapKeyValueAdapter() {
this(ConcurrentHashMap.class);
this(MapKeySpaceStore.create());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to not use the KeySpaceStore static factory methods?

Copy link
Member Author

@mp911de mp911de Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially, a left-over from evolving the interface while moving things around. It lead to some more thoughts on the design and I refined create vs of method naming removing the default ConcurrentHashMap convenience method at KeySpaceStore. We can add it later if necessary and for the time being, we can be less opinionated with the public API while retaining some convenience in our internal code. It's an assumption in the same sense as MapKeySpaceStore is good enough for our own perspective on map storage making it sufficient to pass all tests. Yet, I would not want to expose MapKeySpaceStore as public API because it is an implementation detail. If we see need to evolve an API around the storage itself, then we can take action, but for now, less exposure gives us more flexibility and less API surface.

Optional<String> keySpaceStoreRef = source.getAttribute("keySpaceStoreRef", String.class);

return (Class<? extends Map>) getAnnotationAttributes(source).get("mapType");
return keySpaceStoreRef.map(beanName -> new RuntimeBeanReference(beanName, KeySpaceStore.class)) //
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant to ask (in general) the ending the line w/ // I am guessing makes the formatter not reformat the lines smashed onto a single line and respects the multi-line fluent style that is soothing on the eyes. Is this correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trailing comments force the formatter to keep line breaks. I know that's a style one has to get used to. The motivation is that we want our formatter to generally reformat linebreaks unless we explicitly want to take control. NOFORMAT blocks apply to all aspects of formatting and that is too much exclusion for aspects that matter.

* @author Mark Paluch
*/
@SpringJUnitConfig
class MapDbIntegrationTests {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice test 🎉

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That has been the actual motivation to explore a MapDB integration. MapDB seems to face the face of not being maintained anymore (at least that's my perception) so the outcome of this exercise is an SPI verified against MapDb.

assertThat(adapter).isInstanceOf(MapKeyValueAdapter.class);
assertThat(ReflectionTestUtils.getField(adapter, "store")).isInstanceOf(mapType);

KeySpaceStore store = (KeySpaceStore) ReflectionTestUtils.getField(adapter, "store");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can also be done w/ assertJ directly as it can dig into the fields w/ something like:

assertThat(adapter)
	.extracting("store.store")
	.isInstanceOf(KeySpaceStore.class);

I am guessing you already know this and prefer the more direct error that will result if/when one of the reflected fields is not available?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wootwoot. TIL!

Copy link

@onobc onobc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent improvement @mp911de . I have added a few comments/questions/suggestions - nothing major.

@christophstrobl
Copy link
Member

LGTM

christophstrobl pushed a commit that referenced this pull request Oct 16, 2025
Add KeySpaceStore to retrieve a Map for each keyspace allowing to use a different implementation instead of using generic Java maps. Also, allow configuring KeySpaceStore as bean.

Closes: #71
Original Pull Request: #654
christophstrobl added a commit that referenced this pull request Oct 16, 2025
Original Pull Request: #654
christophstrobl pushed a commit that referenced this pull request Oct 16, 2025
christophstrobl pushed a commit that referenced this pull request Oct 16, 2025
Use RepositoryConfigurationSource for annotation lookup directly.

Original Pull Request: #654
@christophstrobl christophstrobl deleted the issue/71 branch October 16, 2025 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: enhancement A general enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add SPI to provide Map-based repository storage backends

3 participants