Initial Resoning for Optimizer
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/ByteArrayFragment.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/ByteArrayFragment.java
new file mode 100644
index 0000000..69ccf98
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/ByteArrayFragment.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+public class ByteArrayFragment implements Fragment {
+
+ private int id;
+ private final byte[] data;
+ private Ensemble parent;
+
+ public ByteArrayFragment(byte[] data) {
+ this.id = id;
+ this.data = data;
+ }
+
+ @Override public void setId(int id) {
+ this.id = id;
+ }
+
+ @Override public int getId() {
+ return id;
+ }
+
+ @Override public Ensemble getParent() {
+ return this.parent;
+ }
+
+ @Override public void setParent(Ensemble ensemble) {
+ this.parent = ensemble;
+ }
+
+ @Override public byte[] getBytes() {
+ return data;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ByteArrayFragment that = (ByteArrayFragment) o;
+ return id == that.id;
+ }
+
+ @Override public int hashCode() {
+ return Objects.hash(id);
+ }
+
+ @Override public String toString() {
+ return "#" + getId() + " = " + Arrays.toString(data);
+ }
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/Ensemble.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/Ensemble.java
new file mode 100644
index 0000000..a48f3c5
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/Ensemble.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/** Ensemble of fragments that share a stack **/
+public class Ensemble {
+
+ private final AtomicInteger fragmentCounter = new AtomicInteger(0);
+
+ private final Set<Fragment> fragments = new HashSet<>();
+ private final Deque<OptimizerOperation> operations = new LinkedList<>();
+
+ public int getFragmendId() {
+ return fragmentCounter.getAndIncrement();
+ }
+
+ public void addFragment(Fragment fragment) {
+ if (fragment.getParent() != null) {
+ throw new IllegalArgumentException("This Fragment alredy belongs to an ensemble!");
+ }
+ fragment.setId(getFragmendId());
+ fragment.setParent(this);
+ this.fragments.add(fragment);
+ }
+
+ public Set<Fragment> getFragments() {
+ return this.fragments;
+ }
+
+ public void remove(Fragment fragment) {
+ assert fragment.getParent() == this;
+ // Remove by Id
+ this.fragments.remove(fragment);
+ }
+
+ public void addOperation(OptimizerOperation operation) {
+ this.operations.addFirst(operation);
+ }
+
+ @Override public String toString() {
+ return "Ensemble{" +
+ "fragments=" + fragments +
+ ", operations=" + operations +
+ '}';
+ }
+
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/Fragment.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/Fragment.java
new file mode 100644
index 0000000..ba7f3be
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/Fragment.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+/**
+ * Elements the Optimizer works on.
+ * Fragments are data holding elements of a request.
+ */
+public interface Fragment {
+
+ /** Unique Fragment ID **/
+ int getId();
+
+ void setId(int id);
+
+ Ensemble getParent();
+
+ void setParent(Ensemble ensemble);
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/FragmentAdapter.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/FragmentAdapter.java
new file mode 100644
index 0000000..bfec7ec
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/FragmentAdapter.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+public abstract class FragmentAdapter implements Fragment {
+
+ private int id;
+ private Ensemble parent;
+
+ @Override public int getId() {
+ return this.id;
+ }
+
+ @Override public void setId(int id) {
+ this.id = id;
+ }
+
+ @Override public Ensemble getParent() {
+ return this.parent;
+ }
+
+ @Override public void setParent(Ensemble ensemble) {
+ this.parent = ensemble;
+ }
+
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/MergeOperation.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/MergeOperation.java
new file mode 100644
index 0000000..f3f3a00
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/MergeOperation.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+public abstract class MergeOperation implements OptimizerOperation {
+
+ public abstract boolean canMerge(Fragment f1, Fragment f2);
+
+ public abstract Fragment merge(Fragment f1, Fragment f2);
+
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/Optimizer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/Optimizer.java
new file mode 100644
index 0000000..07586d1
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/Optimizer.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * General Principle
+ *
+ * API
+ * S_Req = Set{Req_1{I, ..., I}, ..., Req_n{I, ..., I}}
+ * ------------------
+ * Optimizer
+ * - S_opt = Set{Req*_1{I, ..., I}, ..., Req*_m{I, ..., I}}
+ * - [O_1, ..., O_k] with O_i : Set of Response -> Set of Response
+ * - O_1 : Set{Res*_1, ..., Res*_m} with Res*_1 response to Req*_1, ...
+ * - O_k : Set{Res_1, ..., Res_n} with Res_1 response to Req_1, ...
+ * - Im(O_i) = Sup(O_i+1)
+ * - S* = Set{Res*_1, ..., Res*_m} -- O_1 --> S*_1 ---> .... -- O_k --> S = Set{Res_1, ..., Res_n}
+ * ------------------
+ * Protocol Layer (S*)
+ * ------------------
+ * Deoptimizer Layer (O, S_Res*
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * <code>
+ * Max Packet Size 2
+ * Read: (0 = [1,2,3,4,5])
+ *
+ * Operation 1 : Split
+ * split(1, 2, -> 0) + (1 = [1, 2]), (2 = [3, 4, 5])
+ * Operation 2: Split
+ * merge(3, 4, -> 2) + (1 =)[1, 2]), (3 = [3, 4]), (4 = [5])
+ * </code>
+ */
+public class Optimizer<T extends Fragment> {
+
+ private static final Logger logger = LoggerFactory.getLogger(Optimizer.class);
+
+ private final List<OptimizerCondition> conditions;
+
+ public Optimizer(OptimizerCondition... conditions) {
+ this.conditions = Arrays.asList(conditions);
+ }
+
+ public Ensemble optimize(List<T> fragments) {
+ Ensemble ensemble = new Ensemble();
+ fragments.forEach(ensemble::addFragment);
+
+ logger.info("Starting optimization with Ensembke {}", ensemble);
+ // Check if all Conditions match (return directly?!)
+ boolean violation;
+ do {
+ // TODO this should also skip
+ violation = false;
+ for (OptimizerCondition condition : conditions) {
+ if (condition instanceof SingleFragmentCondition) {
+ for (Fragment fragment : ensemble.getFragments()) {
+ if (((SingleFragmentCondition) condition).applies(fragment)) {
+ logger.warn("The Fragment {} violated constraint {}", fragment, condition);
+ ((SingleFragmentCondition) condition).apply(fragment, ensemble);
+ logger.info("Ensemble is now {}", ensemble);
+ violation = true;
+ }
+ }
+ }
+ }
+ } while (violation);
+ return null;
+ }
+
+ /**
+ * Important, the Fragments have to have identical Fragment ID!
+ */
+ public List<Fragment> deoptimize(Ensemble ensemble, List<ResponseFragment> fragments) {
+ // Check if they match with their id's
+ // Now we create a map id -> fragments to merge them in the appropriate order
+ // Operation (Set<F> -> Set<F>)
+ }
+
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/OptimizerCondition.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/OptimizerCondition.java
new file mode 100644
index 0000000..55397fa
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/OptimizerCondition.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+public interface OptimizerCondition {
+
+ String getName();
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/OptimizerOperation.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/OptimizerOperation.java
new file mode 100644
index 0000000..1979731
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/OptimizerOperation.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+public interface OptimizerOperation {
+
+ String getName();
+
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/RequestFragment.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/RequestFragment.java
new file mode 100644
index 0000000..a276945
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/RequestFragment.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+public abstract class RequestFragment extends FragmentAdapter {
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/ResponseFragment.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/ResponseFragment.java
new file mode 100644
index 0000000..a020034
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/ResponseFragment.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+public abstract class ResponseFragment extends FragmentAdapter {
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/SingleFragmentCondition.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/SingleFragmentCondition.java
new file mode 100644
index 0000000..7cac7d7
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/SingleFragmentCondition.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+import io.vavr.Tuple2;
+
+public interface SingleFragmentCondition extends OptimizerCondition {
+
+ boolean applies(Fragment fragment);
+
+ void apply(Fragment fragment, Ensemble ensemble);
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/SplitOperation.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/SplitOperation.java
new file mode 100644
index 0000000..7d97b94
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/SplitOperation.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+import io.vavr.Tuple2;
+
+public abstract class SplitOperation<T extends Fragment> implements OptimizerOperation {
+
+ public abstract boolean canSplit(T f);
+
+ public abstract Tuple2<MergeOperation, Tuple2<Fragment, Fragment>> split(T f);
+
+}
diff --git a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/optimizer/OptimizerTest.java b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/optimizer/OptimizerTest.java
new file mode 100644
index 0000000..69d45ef
--- /dev/null
+++ b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/optimizer/OptimizerTest.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.plc4x.java.spi.optimizer;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+
+class OptimizerTest {
+
+ @Test
+ void playWithOptimizing() {
+ ByteArrayFragment fragment1 = new ByteArrayFragment(new byte[]{1, 2, 3, 4, 5});
+
+ Optimizer<ByteArrayFragment> optimizer = new Optimizer<>(new MaximalSizeCondition(2));
+
+ // Optimize the ensemble with Conditions
+ optimizer.optimize(Arrays.asList(fragment1));
+ }
+
+ private static class MaximalSizeCondition implements SingleFragmentCondition {
+
+ private final int maximalSize;
+
+ private MaximalSizeCondition(int maximalSize) {
+ this.maximalSize = maximalSize;
+ }
+
+ @Override public boolean applies(Fragment fragment) {
+ if (!(fragment instanceof ByteArrayFragment)) {
+ return false;
+ }
+ return fragment.getBytes().length > maximalSize;
+ }
+
+ @Override public void apply(Fragment fragment, Ensemble ensemble) {
+ // Split it up to two fragments with the appropriate rule
+ byte[] bytes = fragment.getBytes();
+ byte[] first = Arrays.copyOf(bytes, maximalSize);
+ byte[] second = Arrays.copyOfRange(bytes, maximalSize, bytes.length);
+ // Remove our Fragment from the Ensemble and add the two new ones
+ ensemble.remove(fragment);
+ ByteArrayFragment fragment1 = new ByteArrayFragment(first);
+ ByteArrayFragment fragment2 = new ByteArrayFragment(second);
+ ensemble.addFragment(fragment1);
+ ensemble.addFragment(fragment2);
+ // Create Inverse Rule and Register it
+ ensemble.addOperation(new MergeByteArrayFragmentsOp(fragment1.getId(), fragment2.getId(), fragment.getId()));
+ }
+
+ @Override public String toString() {
+ return "MaximumPaketSize(" + maximalSize + ")";
+ }
+
+ @Override public String getName() {
+ return "MaximumPaketSize(" + maximalSize + ")";
+ }
+
+ private static class MergeByteArrayFragmentsOp extends MergeOperation {
+
+ private final int f1;
+ private final int f2;
+ private final int targetId;
+
+ public MergeByteArrayFragmentsOp(int f1, int f2, int targetId) {
+ this.f1 = f1;
+ this.f2 = f2;
+ this.targetId = targetId;
+ }
+
+ @Override public String getName() {
+ return String.format("Merge #%d + #%d -> #%d", f1, f2, targetId);
+ }
+
+ @Override public boolean canMerge(Fragment f1, Fragment f2) {
+ return false;
+ }
+
+ @Override public Fragment merge(Fragment f1, Fragment f2) {
+ return null;
+ }
+
+ @Override public String toString() {
+ return getName();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/site/asciidoc/developers/optimizer.adoc b/src/site/asciidoc/developers/optimizer.adoc
new file mode 100644
index 0000000..7069923
--- /dev/null
+++ b/src/site/asciidoc/developers/optimizer.adoc
@@ -0,0 +1,68 @@
+[ditaa,optimizer-architecture]
+....
++------------------------------------------------+
+|c05A |
+| API |
+| |
++------------------------------------------------+
+ | ^
+ | |
+ | |
+{Req_1, ..., Req_n}<---------------->{n PLC Responses }
+ | |
+ | |
+ | |
++----------------+ |
+|c0FF | |
+| Optimizer |------------------{O_1, ..., O_k}---------------+
+| | | |
++----------------+ | |
+ | | |
+ | | |
+{Q_1, ..., Q_m} | |
+ | | |
+ | | |
+ | | |
++------------------------------------------------+ |
+|c05A | | |
+| v | |
+| +----------------+ | |
+| |c0FF Optimizer | | |
+| +----------------+ | |
+| | |
+| +----------------+ | |
+| |c0FF Optimizer | | |
+| +----------------+ | |
+| | |
++------------------------------------------------+ |
+ | ^ |
+ | | |
+ | | |
+ | {Res_1, ..., Res_n} |
+ | | |
+ | | |
+ | +----------------+ |
+ | |c0FF | |
+ {m PLC Requests }<-----+ | Deoptimizer |<-------------+
+ | | | |
+ | | +----------------+
+ | | ^
+ | | |
+ | | |
+ | +------->{Res_1, ..., Res_m}
+ | |
+ v |
++------------------------------------------------+
+|c05A |
+| Netty |
+| |
++------------------------------------------------+
+....
+
+
+
++----------------+ +----------------+
+|c05A | |c05A |
+| Optimizer | | Optimizer |
+| | | |
++----------------+ +----------------+
\ No newline at end of file