1+ /* *****************************************************************************
2+ *
3+ * Copyright 2021 Nikolay Shaplov (Postgres Professional)
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ *
17+ ******************************************************************************/
18+
119template <class StampT >class StampLottery :public StampT
220{
321protected:
@@ -15,15 +33,39 @@ template<class StampT> class StampLottery: public StampT
1533oracle_size (init_oracle_size(stamps_arg)),
1634 stored_min(init_stored_min(stamps_arg)),
1735 stored_max(init_stored_max(stamps_arg)) {};
18- StampLottery (): stored_min(-1 ), stored_max(-2 ) {};
36+ StampLottery (): stored_min(-1 ), stored_max(-2 ), oracle_size( 1 ) {};
1937
2038virtual int minSize ()override ;
2139virtual int maxSize ()override ;
40+
41+ virtual bool soft_maxsize_filter (StampT &stamp,int data_size) {return true ;};/* Allow to skip stamps that would leave to much data unused. But not active here*/
42+
2243virtual std::stringExtractStr (Blob &blob)override ;
2344void Append (StampT & stamp);
2445};
2546
2647
48+ template <class StampT >class StampLottery4Recursion :public StampLottery <StampT>
49+ {
50+ public:
51+ StampLottery4Recursion (std::ref_vector<StampT> stamps_arg): StampLottery<StampT>(stamps_arg) {};
52+ StampLottery4Recursion (): StampLottery<StampT>() {};
53+ virtual bool soft_maxsize_filter (StampT &stamp,int data_size)override ;
54+ };
55+
56+
57+ template <class StampT >bool
58+ StampLottery4Recursion<StampT>::
59+ soft_maxsize_filter (StampT &stamp,int data_size)
60+ {
61+ if ( stamp.isUnbounded () ||// Unbounded is always ok
62+ stamp.maxSize () > data_size ||// Variated that can consume all data is ok
63+ stamp.minSize () + stamp.maxSize () > data_size// Fixed or variated stamp that lefts less data then it's min size will also do
64+ )
65+ return true ;
66+ return false ;
67+ }
68+
2769template <class StampT >int
2870StampLottery<StampT>::
2971init_stored_min (std::ref_vector<StampT> stamps_arg)
@@ -136,14 +178,9 @@ StampLottery<StampT>::ExtractStr(Blob &blob)
136178for (StampT & stamp : stamps)
137179 {
138180if (blob.Size () < stamp.minSize ())// Skip all stamps that dose not fit
139- continue ;
140- if ( stamp.isUnbounded () ||// Unbounded is always ok
141- stamp.maxSize () > blob.Size () ||// Variated that can consume all data is ok
142- stamp.minSize () *2 > blob.Size ()// Fixed or variated stamp that lefts less data then it's min size will also do
143- )
144- {
181+ continue ;
182+ if (soft_maxsize_filter (stamp, blob.Size ()))
145183 actual_stamps.push_back (stamp);
146- }
147184 }
148185if (actual_stamps.empty ())
149186 {