blob: 07586d12b17ee9a74633943eb980bee0fb020edb [file] [log] [blame]
/*
* 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>)
}
}