@@ -156,21 +156,63 @@ public static function getStatistics(): array
156156 $ totalOperations = (int )self ::$ stats ['allocations ' ] + (int )self ::$ stats ['reuses ' ];
157157 $ reuseRate = $ totalOperations > 0 ? ((int )self ::$ stats ['reuses ' ] / $ totalOperations ) * 100 : 0 ;
158158
159+ // Map pool keys to readable format with capacity information
159160 $ poolSizes = [];
161+ $ poolsByCapacity = [];
162+ $ totalBuffersInPools = 0 ;
163+
160164 foreach (self ::$ pools as $ key => $ pool ) {
161- $ poolSizes [$ key ] = count ($ pool );
165+ $ poolSize = count ($ pool );
166+ $ totalBuffersInPools += $ poolSize ;
167+
168+ // Extract capacity from key (format: "buffer_{capacity}")
169+ if (preg_match ('/^buffer_(\d+)$/ ' , $ key , $ matches )) {
170+ $ capacity = (int )$ matches [1 ];
171+ $ readableKey = self ::formatCapacity ($ capacity );
172+
173+ $ poolSizes [$ readableKey ] = $ poolSize ;
174+ $ poolsByCapacity [$ capacity ] = [
175+ 'key ' => $ key ,
176+ 'capacity_bytes ' => $ capacity ,
177+ 'capacity_formatted ' => $ readableKey ,
178+ 'buffers_available ' => $ poolSize
179+ ];
180+ } else {
181+ // Fallback for unexpected key format
182+ $ poolSizes [$ key ] = $ poolSize ;
183+ }
162184 }
163185
186+ // Sort pools by capacity for better readability
187+ ksort ($ poolsByCapacity );
188+
164189 return [
165190 'reuse_rate ' => round ($ reuseRate , 2 ),
166191 'total_operations ' => $ totalOperations ,
167192 'current_usage ' => self ::$ stats ['current_usage ' ],
168193 'peak_usage ' => self ::$ stats ['peak_usage ' ],
169- 'pool_sizes ' => $ poolSizes ,
194+ 'total_buffers_pooled ' => $ totalBuffersInPools ,
195+ 'active_pool_count ' => count (self ::$ pools ),
196+ 'pool_sizes ' => $ poolSizes , // Legacy format for backward compatibility
197+ 'pools_by_capacity ' => array_values ($ poolsByCapacity ), // Enhanced format
170198 'detailed_stats ' => self ::$ stats
171199 ];
172200 }
173201
202+ /**
203+ * Format capacity in human-readable form
204+ */
205+ private static function formatCapacity (int $ bytes ): string
206+ {
207+ if ($ bytes >= 1024 * 1024 ) {
208+ return sprintf ('%.1fMB (%d bytes) ' , $ bytes / (1024 * 1024 ), $ bytes );
209+ } elseif ($ bytes >= 1024 ) {
210+ return sprintf ('%.1fKB (%d bytes) ' , $ bytes / 1024 , $ bytes );
211+ } else {
212+ return sprintf ('%d bytes ' , $ bytes );
213+ }
214+ }
215+
174216 /**
175217 * Clear all pools (useful for testing)
176218 */
@@ -186,14 +228,100 @@ public static function clearPools(): void
186228 ];
187229 }
188230
231+ /**
232+ * Reset configuration to defaults (useful for testing)
233+ */
234+ public static function resetConfiguration (): void
235+ {
236+ self ::$ config = [
237+ 'max_pool_size ' => 50 ,
238+ 'default_capacity ' => 4096 ,
239+ 'size_categories ' => [
240+ 'small ' => 1024 , // 1KB
241+ 'medium ' => 4096 , // 4KB
242+ 'large ' => 16384 , // 16KB
243+ 'xlarge ' => 65536 // 64KB
244+ ]
245+ ];
246+ }
247+
189248 /**
190249 * Configure pool settings
191250 */
192251 public static function configure (array $ config ): void
193252 {
253+ self ::validateConfiguration ($ config );
194254 self ::$ config = array_merge (self ::$ config , $ config );
195255 }
196256
257+ /**
258+ * Validate configuration parameters
259+ */
260+ private static function validateConfiguration (array $ config ): void
261+ {
262+ // Validate 'max_pool_size'
263+ if (isset ($ config ['max_pool_size ' ])) {
264+ if (!is_int ($ config ['max_pool_size ' ]) || $ config ['max_pool_size ' ] <= 0 ) {
265+ throw new \InvalidArgumentException ("'max_pool_size' must be a positive integer, got: " . gettype ($ config ['max_pool_size ' ]));
266+ }
267+ if ($ config ['max_pool_size ' ] > 1000 ) {
268+ throw new \InvalidArgumentException ("'max_pool_size' cannot exceed 1000 for memory safety, got: {$ config ['max_pool_size ' ]}" );
269+ }
270+ }
271+
272+ // Validate 'default_capacity'
273+ if (isset ($ config ['default_capacity ' ])) {
274+ if (!is_int ($ config ['default_capacity ' ]) || $ config ['default_capacity ' ] <= 0 ) {
275+ throw new \InvalidArgumentException ("'default_capacity' must be a positive integer, got: " . gettype ($ config ['default_capacity ' ]));
276+ }
277+ if ($ config ['default_capacity ' ] > 1024 * 1024 ) { // 1MB limit
278+ throw new \InvalidArgumentException ("'default_capacity' cannot exceed 1MB (1048576 bytes), got: {$ config ['default_capacity ' ]}" );
279+ }
280+ }
281+
282+ // Validate 'size_categories'
283+ if (isset ($ config ['size_categories ' ])) {
284+ if (!is_array ($ config ['size_categories ' ])) {
285+ throw new \InvalidArgumentException ("'size_categories' must be an array, got: " . gettype ($ config ['size_categories ' ]));
286+ }
287+
288+ if (empty ($ config ['size_categories ' ])) {
289+ throw new \InvalidArgumentException ("'size_categories' cannot be empty " );
290+ }
291+
292+ foreach ($ config ['size_categories ' ] as $ name => $ capacity ) {
293+ if (!is_string ($ name ) || empty ($ name )) {
294+ throw new \InvalidArgumentException ("Size category names must be non-empty strings " );
295+ }
296+
297+ if (!is_int ($ capacity ) || $ capacity <= 0 ) {
298+ throw new \InvalidArgumentException ("Size category ' {$ name }' must have a positive integer capacity, got: " . gettype ($ capacity ));
299+ }
300+
301+ if ($ capacity > 1024 * 1024 ) { // 1MB limit per category
302+ throw new \InvalidArgumentException ("Size category ' {$ name }' capacity cannot exceed 1MB (1048576 bytes), got: {$ capacity }" );
303+ }
304+ }
305+
306+ // Validate categories are in ascending order for optimal selection
307+ $ capacities = array_values ($ config ['size_categories ' ]);
308+ $ sortedCapacities = $ capacities ;
309+ sort ($ sortedCapacities );
310+
311+ if ($ capacities !== $ sortedCapacities ) {
312+ throw new \InvalidArgumentException ("'size_categories' should be ordered from smallest to largest capacity for optimal selection " );
313+ }
314+ }
315+
316+ // Check for unknown configuration keys
317+ $ validKeys = ['max_pool_size ' , 'default_capacity ' , 'size_categories ' ];
318+ $ unknownKeys = array_diff (array_keys ($ config ), $ validKeys );
319+
320+ if (!empty ($ unknownKeys )) {
321+ throw new \InvalidArgumentException ("Unknown configuration keys: " . implode (', ' , $ unknownKeys ));
322+ }
323+ }
324+
197325 /**
198326 * Get pool key for given capacity
199327 */
0 commit comments