From de619315922a10309045f161d793ce8a77b5b830 Mon Sep 17 00:00:00 2001 From: FarhanAnjum-opti Date: Wed, 2 Jul 2025 05:48:26 +0600 Subject: [PATCH 1/3] update: Extend LRUCache with remove method and corresponding tests --- lib/optimizely/odp/lru_cache.rb | 15 ++++++- spec/odp/lru_cache_spec.rb | 80 +++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/lib/optimizely/odp/lru_cache.rb b/lib/optimizely/odp/lru_cache.rb index 8ce61549..23bf4e67 100644 --- a/lib/optimizely/odp/lru_cache.rb +++ b/lib/optimizely/odp/lru_cache.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # -# Copyright 2022, Optimizely and contributors +# Copyright 2022-2025, Optimizely and contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -91,6 +91,19 @@ def peek(key) @cache_mutex.synchronize { @map[key]&.value } end + + # Remove the element associated with the provided key from the cache + # + # @param key - The key to remove + + def remove(key) + return if @capacity <= 0 + + @cache_mutex.synchronize do + @map.delete(key) + end + nil + end end class CacheElement diff --git a/spec/odp/lru_cache_spec.rb b/spec/odp/lru_cache_spec.rb index 46363c8b..deafeecc 100644 --- a/spec/odp/lru_cache_spec.rb +++ b/spec/odp/lru_cache_spec.rb @@ -149,4 +149,84 @@ cache.save('cow', 'crate') expect(cache.lookup('cow')).to eq 'crate' end + + it 'should remove existing key' do + cache = Optimizely::LRUCache.new(3, 1000) + + cache.save('1', 100) + cache.save('2', 200) + cache.save('3', 300) + + expect(cache.lookup('1')).to eq 100 + expect(cache.lookup('2')).to eq 200 + expect(cache.lookup('3')).to eq 300 + + cache.remove('2') + + expect(cache.lookup('1')).to eq 100 + expect(cache.lookup('2')).to be_nil + expect(cache.lookup('3')).to eq 300 + end + + it 'should handle removing non-existent key' do + cache = Optimizely::LRUCache.new(3, 1000) + cache.save('1', 100) + cache.save('2', 200) + + cache.remove('3') # Doesn't exist + + expect(cache.lookup('1')).to eq 100 + expect(cache.lookup('2')).to eq 200 + end + + it 'should handle removing from zero sized cache' do + cache = Optimizely::LRUCache.new(0, 1000) + cache.save('1', 100) + cache.remove('1') + + expect(cache.lookup('1')).to be_nil + end + + it 'should handle removing and adding back a key' do + cache = Optimizely::LRUCache.new(3, 1000) + cache.save('1', 100) + cache.save('2', 200) + cache.save('3', 300) + + cache.remove('2') + cache.save('2', 201) + + expect(cache.lookup('1')).to eq 100 + expect(cache.lookup('2')).to eq 201 + expect(cache.lookup('3')).to eq 300 + end + + it 'should handle thread safety' do + max_size = 100 + cache = Optimizely::LRUCache.new(max_size, 1000) + + (1..max_size).each do |i| + cache.save(i.to_s, i * 100) + end + + threads = [] + (1..(max_size / 2)).each do |i| + thread = Thread.new do + cache.remove(i.to_s) + end + threads << thread + end + + threads.each(&:join) + + (1..max_size).each do |i| + if i <= max_size / 2 + expect(cache.lookup(i.to_s)).to be_nil + else + expect(cache.lookup(i.to_s)).to eq(i * 100) + end + end + + expect(cache.instance_variable_get('@map').size).to eq(max_size / 2) + end end From 01e3a9f8545afd2b9700be5975a327bb57b7355a Mon Sep 17 00:00:00 2001 From: FarhanAnjum-opti Date: Wed, 2 Jul 2025 05:52:03 +0600 Subject: [PATCH 2/3] update: Clean up whitespace in LRUCache implementation and tests --- lib/optimizely/odp/lru_cache.rb | 2 +- spec/odp/lru_cache_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/optimizely/odp/lru_cache.rb b/lib/optimizely/odp/lru_cache.rb index 23bf4e67..6d4c9af3 100644 --- a/lib/optimizely/odp/lru_cache.rb +++ b/lib/optimizely/odp/lru_cache.rb @@ -91,7 +91,7 @@ def peek(key) @cache_mutex.synchronize { @map[key]&.value } end - + # Remove the element associated with the provided key from the cache # # @param key - The key to remove diff --git a/spec/odp/lru_cache_spec.rb b/spec/odp/lru_cache_spec.rb index deafeecc..8c65d909 100644 --- a/spec/odp/lru_cache_spec.rb +++ b/spec/odp/lru_cache_spec.rb @@ -173,7 +173,7 @@ cache.save('1', 100) cache.save('2', 200) - cache.remove('3') # Doesn't exist + cache.remove('3') # Doesn't exist expect(cache.lookup('1')).to eq 100 expect(cache.lookup('2')).to eq 200 From 40d0571ca4cf01f12d497b7851a335995b092114 Mon Sep 17 00:00:00 2001 From: FarhanAnjum-opti Date: Wed, 2 Jul 2025 05:52:38 +0600 Subject: [PATCH 3/3] update: Extend copyright notice to include 2025 --- spec/odp/lru_cache_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/odp/lru_cache_spec.rb b/spec/odp/lru_cache_spec.rb index 8c65d909..32db021f 100644 --- a/spec/odp/lru_cache_spec.rb +++ b/spec/odp/lru_cache_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # -# Copyright 2022, Optimizely and contributors +# Copyright 2022-2025, Optimizely and contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License.