Hone logo
Hone
Problems

Rust Data Structure for Efficient Feature Flag Management

This challenge focuses on building a robust and efficient Rust data structure to manage feature flags for an application. Feature flags allow developers to dynamically enable or disable functionalities without deploying new code, which is crucial for A/B testing, gradual rollouts, and quick rollback of problematic features.

Problem Description

You need to implement a Rust FeatureManager struct that can store and retrieve the state of various feature flags. Each feature flag will have a unique string identifier and can be either enabled or disabled. The FeatureManager should support adding new feature flags, enabling/disabling them, and checking their current status.

Key Requirements:

  1. Initialization: The FeatureManager should be creatable.
  2. Adding Features: A method to add a new feature flag with a given identifier and an initial state (enabled or disabled).
  3. Enabling/Disabling: Methods to enable or disable a specific feature flag by its identifier.
  4. Checking Status: A method to check if a feature flag is currently enabled.
  5. Handling Non-existent Features: When trying to enable, disable, or check the status of a feature flag that hasn't been added, the manager should handle this gracefully.

Expected Behavior:

  • Adding a feature flag that already exists should either update its state or be ignored (your choice, but clearly document it).
  • Enabling or disabling a non-existent feature flag should not cause a panic.
  • Checking the status of a non-existent feature flag should return false (as if it's disabled).

Edge Cases to Consider:

  • Empty FeatureManager when performing operations.
  • Adding duplicate feature flags.
  • Performing operations on feature flags after they have been enabled/disabled multiple times.
  • Case sensitivity of feature flag identifiers.

Examples

Example 1:

Input:
let mut manager = FeatureManager::new();
manager.add_feature("new_dashboard", true); // Add with initial state enabled
manager.enable_feature("experimental_search"); // Add and enable
manager.disable_feature("old_api_support"); // Add and disable

Output (after operations):
manager.is_feature_enabled("new_dashboard") -> true
manager.is_feature_enabled("experimental_search") -> true
manager.is_feature_enabled("old_api_support") -> false
manager.is_feature_enabled("non_existent_feature") -> false

Explanation:
- "new_dashboard" was added as enabled.
- "experimental_search" was added and then enabled.
- "old_api_support" was added and then disabled.
- "non_existent_feature" was never added, so its status defaults to false.

Example 2:

Input:
let mut manager = FeatureManager::new();
manager.add_feature("beta_feature", false);
manager.enable_feature("beta_feature");
manager.disable_feature("beta_feature");
manager.enable_feature("beta_feature");

Output (after operations):
manager.is_feature_enabled("beta_feature") -> true

Explanation:
The state of "beta_feature" is toggled multiple times, and its final state is enabled.

Example 3: (Handling non-existent features)

Input:
let mut manager = FeatureManager::new();

Output (after operations):
manager.is_feature_enabled("any_feature") -> false
manager.enable_feature("any_feature") // This should not panic
manager.disable_feature("any_feature") // This should not panic
manager.is_feature_enabled("any_feature") -> false // Assuming enable/disable on non-existent has no persistent effect

Explanation:
Operations on features that do not exist are handled without errors, and their status remains effectively false.

Constraints

  • Feature flag identifiers are case-sensitive strings.
  • The number of feature flags can be large (e.g., up to 10,000).
  • Operations (add, enable, disable, check) should ideally have an average time complexity of O(1) or O(log N) where N is the number of features.
  • The FeatureManager should be thread-safe if possible, though this is a secondary goal for this specific challenge. Focus on correctness and efficiency first.

Notes

Consider using a suitable Rust collection to store the feature flags. Think about how to efficiently map feature flag identifiers to their boolean states. For handling non-existent features, consider using Option or default values. You will need to define the FeatureManager struct and implement the required methods.

Loading editor...
rust