@@ -50,4 +50,68 @@ def compare_sps(previous_df, current_df, workload_cols, feature_cols):
5050
5151 changed_df = changed_df [current_df .columns ]
5252
53- return changed_df if not changed_df .empty else None
53+ return changed_df if not changed_df .empty else None
54+
55+ def compare_max_instance (previous_df , new_df , target_capacity ):
56+ fallback_dict = {50 :45 , 45 :40 , 40 :35 , 35 :30 , 30 :25 , 25 :20 , 20 :15 , 15 :10 , 10 :5 , 5 :1 , 1 :0 }
57+ fallback_val = fallback_dict .get (target_capacity , 0 )
58+
59+ merged_df = pd .merge (
60+ new_df ,
61+ previous_df [["InstanceType" , "Region" , "AvailabilityZone" , "DesiredCount" , "Score" , "T3" , "T2" ]],
62+ on = ["InstanceType" , "Region" , "AvailabilityZone" , "DesiredCount" ],
63+ how = "left" ,
64+ suffixes = ("" , "_prev" )
65+ )
66+
67+ # Fix SPS when single node SPS
68+ if target_capacity == 1 :
69+ merged_df ["Score" ] = merged_df ["Score" ].combine_first (merged_df ["Score_prev" ])
70+
71+ # Merge single node SPS with multi node SPS if (multi node SPS) > (single node SPS)
72+ # Note: Score strings "3", "2", "1" are comparable.
73+ # But need to handle N/A or types. Assuming Score is int or convertible.
74+ # Azure Score is int from load_sps.
75+ # previous_df Score might be string if read from file? feature_cols convert to str in compare_sps but here we read raw df.
76+
77+ # Ensure Score types are compatible (float/int)
78+ merged_df ["Score" ] = pd .to_numeric (merged_df ["Score" ], errors = 'coerce' )
79+ merged_df ["Score_prev" ] = pd .to_numeric (merged_df ["Score_prev" ], errors = 'coerce' )
80+ merged_df ["T3" ] = pd .to_numeric (merged_df ["T3" ], errors = 'coerce' ).fillna (0 )
81+ merged_df ["T3_prev" ] = pd .to_numeric (merged_df ["T3_prev" ], errors = 'coerce' ).fillna (0 )
82+ merged_df ["T2" ] = pd .to_numeric (merged_df ["T2" ], errors = 'coerce' ).fillna (0 )
83+ merged_df ["T2_prev" ] = pd .to_numeric (merged_df ["T2_prev" ], errors = 'coerce' ).fillna (0 )
84+
85+ merged_df .loc [(merged_df ["Score" ] > merged_df ["Score_prev" ]), "Score_prev" ] = merged_df ["Score" ]
86+
87+ # Calculate T3
88+ # Use numpy where.
89+ merged_df ["T3" ] = np .where (
90+ merged_df ["Score" ] >= 3 ,
91+ np .maximum (merged_df ["T3" ], merged_df ["T3_prev" ]),
92+ np .minimum (fallback_val , merged_df ["T3_prev" ])
93+ )
94+
95+ # Calculate T2
96+ merged_df ["T2" ] = np .where (
97+ merged_df ["Score" ] >= 2 ,
98+ np .maximum (merged_df ["T2" ], merged_df ["T2_prev" ]),
99+ np .minimum (fallback_val , merged_df ["T2_prev" ])
100+ )
101+
102+ if target_capacity == 1 :
103+ merged_df .loc [merged_df ["Score" ] <= 2 , "T3" ] = 0
104+ merged_df .loc [merged_df ["Score" ] < 2 , "T2" ] = 0
105+ else :
106+ merged_df .loc [merged_df ["Score_prev" ] <= 2 , "T3" ] = 0
107+ merged_df .loc [merged_df ["Score_prev" ] < 2 , "T2" ] = 0
108+ # Fix SPS to Single node SPS ? mimic AWS "merged_df["SPS"] = merged_df["SPS_prev"]"
109+ # AWS comment: "Fix SPS to Single node SPS" - this logic seems specific to assuming single node fallback.
110+ # But let's copy logic:
111+ merged_df ["Score" ] = merged_df ["Score_prev" ]
112+
113+ # Convert to standard types if needed
114+ # Drop unnecessary columns
115+ merged_df .drop (columns = ["T3_prev" , "T2_prev" , "Score_prev" ], errors = 'ignore' , inplace = True )
116+
117+ return merged_df
0 commit comments