jhalterman / expiringmap

A high performance thread-safe map that expires entries
Apache License 2.0
1k stars 142 forks source link

When using foreach, the keyset method loops infinitely #70

Open bigzibo opened 3 years ago

bigzibo commented 3 years ago

code public static void main(String[] args) { ExpiringMap<String, String> map = ExpiringMap.builder() .maxSize(100) .expiration(20L, TimeUnit.MINUTES) .expirationPolicy(ExpirationPolicy.ACCESSED) .variableExpiration() .build(); map.put("1", "1"); map.put("2", "2"); map.keySet().forEach((key) -> { System.out.println(map.get(key)); }); }

and result 1 2 1 2 1 2 1 2 .....

bigzibo commented 3 years ago
    <dependency>
        <groupId>net.jodah</groupId>
        <artifactId>expiringmap</artifactId>
        <version>0.5.9</version>
    </dependency>
jhalterman commented 3 years ago

Happy to take a PR for this.

r0b0ji commented 3 years ago

There is something wrong when ExpirationPolicy is ACCESSED. For ex:

This works.

 @Test
  public void testLoopTerminates() {
    ExpiringMap<String, String> map = ExpiringMap.builder()
            .maxSize(100)
            .expiration(20L, TimeUnit.MINUTES)
            .expirationPolicy(ExpirationPolicy.CREATED)
            .variableExpiration()
            .build();

    map.put("1", "1");
    map.put("2", "2");

    map.keySet().forEach(key -> System.out.println(map.get(key)));
  }

But this doesn't.

@Test
  public void testLoop() {
    ExpiringMap<String, String> map = ExpiringMap.builder()
            .maxSize(100)
            .expiration(20L, TimeUnit.MINUTES)
            .expirationPolicy(ExpirationPolicy.ACCESSED)
            .variableExpiration()
            .build();

    map.put("1", "1");
    map.put("2", "2");

    map.keySet().forEach(key -> System.out.println(map.get(key)));
  }
r0b0ji commented 3 years ago

This is a bug.

r0b0ji commented 3 years ago

The bug is that get > resetEntry (if policy is accessed) > reorder (removes and add)

This looks like a bug, that it adds again, so when I removed the reorder line, it worked fine but then I am not sure if that is correct fix.