-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implementation of memory persistence service.
This persistence service is self-contained and allows to retain data without disk/storage access. It can be also used for items which have high update frequency and might put unecessary load on storage. Signed-off-by: Łukasz Dywicki <luke@code-house.org>
- Loading branch information
Showing
10 changed files
with
773 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
- Copyright (C) 2024-2024 ConnectorIO Sp. z o.o. | ||
- | ||
- 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. | ||
- | ||
- SPDX-License-Identifier: Apache-2.0 | ||
--> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
|
||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>org.connectorio.addons</groupId> | ||
<artifactId>bundles</artifactId> | ||
<version>3.0.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>org.connectorio.addons.persistence.memory</artifactId> | ||
<packaging>bundle</packaging> | ||
|
||
<name>ConnectorIO - Addons - Persistence - Memory</name> | ||
<description>A memory persistence service.</description> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.openhab.core.bundles</groupId> | ||
<artifactId>org.openhab.core.persistence</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.openhab.core.bundles</groupId> | ||
<artifactId>org.openhab.core.config.xml</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.thoughtworks.xstream</groupId> | ||
<artifactId>xstream</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-api</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.osgi</groupId> | ||
<artifactId>osgi.core</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.osgi</groupId> | ||
<artifactId>org.osgi.service.component.annotations</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter-api</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter-params</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.assertj</groupId> | ||
<artifactId>assertj-core</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.mockito</groupId> | ||
<artifactId>mockito-junit-jupiter</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.connectorio.addons</groupId> | ||
<artifactId>org.connectorio.addons.test</artifactId> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
121 changes: 121 additions & 0 deletions
121
...memory/src/main/java/org/connectorio/addons/persistence/memory/internal/MemoryBucket.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/* | ||
* Copyright (C) 2024-2024 ConnectorIO Sp. z o.o. | ||
* | ||
* 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. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
package org.connectorio.addons.persistence.memory.internal; | ||
|
||
import java.util.Comparator; | ||
import java.util.Date; | ||
import java.util.NavigableSet; | ||
import java.util.Objects; | ||
import java.util.TreeSet; | ||
import java.util.concurrent.locks.Lock; | ||
import java.util.concurrent.locks.ReentrantLock; | ||
import java.util.function.Consumer; | ||
import java.util.function.Function; | ||
import java.util.stream.Stream; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class MemoryBucket { | ||
|
||
private final Logger logger = LoggerFactory.getLogger(MemoryBucket.class); | ||
|
||
private final NavigableSet<MemoryEntry> entries = new TreeSet<>( | ||
Comparator.comparing(MemoryEntry::getTimestamp) | ||
); | ||
|
||
private final Lock lock = new ReentrantLock(); | ||
private int limit; | ||
|
||
public MemoryBucket(int limit) { | ||
this.limit = limit; | ||
} | ||
|
||
public void append(MemoryEntry entry) { | ||
apply(myself -> { | ||
logger.trace("Inserted entry {}. Stored entries {}, limit {}", entry, entries.size(), limit); | ||
myself.entries.add(entry); | ||
}); | ||
} | ||
|
||
public void truncate(int limit) { | ||
this.limit = limit; | ||
|
||
apply(myself -> { | ||
while (myself.entries.size() > limit) { | ||
MemoryEntry entry = myself.entries.pollFirst(); | ||
logger.trace("Removed bucket entry {} as it exceeds limit {}", entry, limit); | ||
} | ||
}); | ||
} | ||
|
||
public Stream<MemoryEntry> entries() { | ||
return entries.stream(); | ||
} | ||
|
||
public void remove(MemoryEntry entry) { | ||
apply(myself -> myself.entries.remove(entry)); | ||
} | ||
|
||
public Integer getSize() { | ||
return entries.size(); | ||
} | ||
|
||
public Date getEarliest() { | ||
return entries.isEmpty() ? null : Date.from(entries.first().getTimestamp().toInstant()); | ||
} | ||
|
||
public Date getOldest() { | ||
return entries.isEmpty() ? null : Date.from(entries.last().getTimestamp().toInstant()); | ||
} | ||
|
||
public <X> X process(Function<MemoryBucket, X> function) { | ||
lock.lock(); | ||
try { | ||
return function.apply(this); | ||
} finally { | ||
lock.unlock(); | ||
} | ||
} | ||
|
||
private void apply(Consumer<MemoryBucket> consumer) { | ||
lock.lock(); | ||
try { | ||
consumer.accept(this); | ||
} finally { | ||
lock.unlock(); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (!(o instanceof MemoryBucket)) { | ||
return false; | ||
} | ||
MemoryBucket bucket = (MemoryBucket) o; | ||
return limit == bucket.limit && Objects.equals(entries, bucket.entries); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(entries, limit); | ||
} | ||
|
||
} |
57 changes: 57 additions & 0 deletions
57
...ry/src/main/java/org/connectorio/addons/persistence/memory/internal/MemoryBucketInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright (C) 2024-2024 ConnectorIO Sp. z o.o. | ||
* | ||
* 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. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
package org.connectorio.addons.persistence.memory.internal; | ||
|
||
import java.util.Date; | ||
import org.openhab.core.persistence.PersistenceItemInfo; | ||
|
||
public class MemoryBucketInfo implements PersistenceItemInfo { | ||
|
||
private final String name; | ||
private final Integer count; | ||
private final Date earliest; | ||
private final Date oldest; | ||
|
||
public MemoryBucketInfo(String name, Integer count, Date earliest, Date oldest) { | ||
this.name = name; | ||
this.count = count; | ||
this.earliest = earliest; | ||
this.oldest = oldest; | ||
} | ||
|
||
|
||
@Override | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
@Override | ||
public Integer getCount() { | ||
return count; | ||
} | ||
|
||
@Override | ||
public Date getEarliest() { | ||
return earliest; | ||
} | ||
|
||
@Override | ||
public Date getLatest() { | ||
return oldest; | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
....memory/src/main/java/org/connectorio/addons/persistence/memory/internal/MemoryEntry.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* Copyright (C) 2024-2024 ConnectorIO Sp. z o.o. | ||
* | ||
* 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. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
package org.connectorio.addons.persistence.memory.internal; | ||
|
||
import java.time.ZonedDateTime; | ||
import java.util.Objects; | ||
import org.openhab.core.types.State; | ||
|
||
public class MemoryEntry { | ||
|
||
private final ZonedDateTime timestamp; | ||
private final State state; | ||
|
||
public MemoryEntry(ZonedDateTime timestamp, State state) { | ||
this.timestamp = timestamp; | ||
this.state = state; | ||
} | ||
|
||
public ZonedDateTime getTimestamp() { | ||
return timestamp; | ||
} | ||
|
||
public State getState() { | ||
return state; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (!(o instanceof MemoryEntry)) { | ||
return false; | ||
} | ||
MemoryEntry that = (MemoryEntry) o; | ||
return Objects.equals(getTimestamp(), that.getTimestamp()) && Objects.equals( | ||
getState(), that.getState()); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(getTimestamp(), getState()); | ||
} | ||
|
||
public String toString() { | ||
return "MemoryEntry [" + timestamp + "=" + state + "]"; | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
.../src/main/java/org/connectorio/addons/persistence/memory/internal/MemoryHistoricItem.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (C) 2024-2024 ConnectorIO Sp. z o.o. | ||
* | ||
* 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. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
package org.connectorio.addons.persistence.memory.internal; | ||
|
||
import java.time.ZonedDateTime; | ||
import org.openhab.core.persistence.HistoricItem; | ||
import org.openhab.core.types.State; | ||
|
||
public class MemoryHistoricItem implements HistoricItem { | ||
private final String name; | ||
private final ZonedDateTime timestamp; | ||
private final State state; | ||
|
||
public MemoryHistoricItem(String name, ZonedDateTime timestamp, State state) { | ||
this.name = name; | ||
this.timestamp = timestamp; | ||
this.state = state; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
@Override | ||
public ZonedDateTime getTimestamp() { | ||
return timestamp; | ||
} | ||
|
||
@Override | ||
public State getState() { | ||
return state; | ||
} | ||
|
||
} |
Oops, something went wrong.