{"record":{"id":"ccf60c828428270f","repo":"nathanmarz/storm","slug":"numbuckets-must-be-2","errorCode":null,"errorMessage":"numBuckets must be >= 2","messagePattern":"numBuckets must be >= 2","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"storm-core/src/jvm/backtype/storm/utils/RotatingMap.java","lineNumber":50,"sourceCode":" *\n * The advantage of this design is that the expiration thread only locks the object\n * for O(1) time, meaning the object is essentially always available for gets/puts.\n */\npublic class RotatingMap<K, V> {\n    //this default ensures things expire at most 50% past the expiration time\n    private static final int DEFAULT_NUM_BUCKETS = 3;\n\n    public static interface ExpiredCallback<K, V> {\n        public void expire(K key, V val);\n    }\n\n    private LinkedList<HashMap<K, V>> _buckets;\n\n    private ExpiredCallback _callback;\n    \n    public RotatingMap(int numBuckets, ExpiredCallback<K, V> callback) {\n        if(numBuckets<2) {\n            throw new IllegalArgumentException(\"numBuckets must be >= 2\");\n        }\n        _buckets = new LinkedList<HashMap<K, V>>();\n        for(int i=0; i<numBuckets; i++) {\n            _buckets.add(new HashMap<K, V>());\n        }\n\n        _callback = callback;\n    }\n\n    public RotatingMap(ExpiredCallback<K, V> callback) {\n        this(DEFAULT_NUM_BUCKETS, callback);\n    }\n\n    public RotatingMap(int numBuckets) {\n        this(numBuckets, null);\n    }   \n    \n    public Map<K, V> rotate() {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/nathanmarz/storm/blob/cdb116e942666973bc4eaa0df098d5bab82739e7/storm-core/src/jvm/backtype/storm/utils/RotatingMap.java#L32-L68","documentation":"Thrown by the RotatingMap constructor as a guard against an invalid numBuckets argument: a rotating-bucket expiration map needs at least 2 buckets because rotation always leaves one bucket untouched per cycle, and with fewer than 2 buckets items would expire immediately or rotation would be meaningless.","triggerScenarios":"Thrown at storm-core/src/jvm/backtype/storm/utils/RotatingMap.java:50 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Construct RotatingMap with numBuckets >= 2.","Use the no-arg constructor (defaults to 3 buckets) when unsure.","Review any configuration value feeding numBuckets (e.g. from topology config) and clamp it to a minimum of 2.","Recall bucket count affects expiration timing: effective expiry is between numBuckets and 2*numBuckets rotation periods."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"cdb116e942666973bc4eaa0df098d5bab82739e7","analyzedAt":"2026-09-12T14:30:00.714Z","contentChangedAt":"2026-09-12T14:30:00.714Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}