From d9bc5102aeb20bd6744077bd2fd174ed9335cd91 Mon Sep 17 00:00:00 2001 From: James Hilliard Date: Thu, 27 May 2021 00:43:00 -0600 Subject: [PATCH 1/2] Use monotonic clocks for TSpace. --- jpos/src/main/java/org/jpos/space/TSpace.java | 62 ++++++++++--------- .../org/jpos/space/TSpacePerformanceTest.java | 5 +- .../test/java/org/jpos/space/TSpaceTest.java | 29 ++++----- .../java/org/jpos/space/TSpaceTestCase.java | 13 ++-- 4 files changed, 56 insertions(+), 53 deletions(-) diff --git a/jpos/src/main/java/org/jpos/space/TSpace.java b/jpos/src/main/java/org/jpos/space/TSpace.java index e34471140c..14ef344d90 100644 --- a/jpos/src/main/java/org/jpos/space/TSpace.java +++ b/jpos/src/main/java/org/jpos/space/TSpace.java @@ -18,10 +18,10 @@ package org.jpos.space; import org.jpos.util.Loggeable; + import java.io.PrintStream; import java.io.Serializable; import java.time.Duration; -import java.time.Instant; import java.util.*; import java.util.concurrent.TimeUnit; @@ -41,7 +41,7 @@ public class TSpace implements LocalSpace, Loggeable, Runnable { private static final long NRD_RESOLUTION = 500L; private static final int MAX_ENTRIES_IN_DUMP = 1000; private final Set[] expirables; - private long lastLongGC = Instant.now().toEpochMilli(); + private Duration lastLongGC = Duration.ofNanos(System.nanoTime()); public TSpace () { super(); @@ -70,7 +70,7 @@ public void out (K key, V value, long timeout) { throw new NullPointerException ("key=" + key + ", value=" + value); Object v = value; if (timeout > 0) { - v = new Expirable (value, Instant.now().toEpochMilli() + timeout); + v = new Expirable (value, Duration.ofNanos(System.nanoTime()).plus(Duration.ofMillis(timeout))); } synchronized (this) { List l = getList(key); @@ -113,13 +113,14 @@ public synchronized V in (Object key) { @Override public synchronized V in (Object key, long timeout) { Object obj; - Instant now = Instant.now(); - long duration; + Duration to = Duration.ofMillis(timeout); + Duration now = Duration.ofNanos(System.nanoTime()); + Duration duration; while ((obj = inp (key)) == null && - (duration = Duration.between(now, Instant.now()).toMillis()) < timeout) + to.compareTo(duration = Duration.ofNanos(System.nanoTime()).minus(now)) > 0) { try { - this.wait (timeout - duration); + this.wait (Math.max(to.minus(duration).toMillis(), 1L)); } catch (InterruptedException e) { } } return (V) obj; @@ -139,13 +140,14 @@ public synchronized V rd (Object key) { @Override public synchronized V rd (Object key, long timeout) { Object obj; - Instant now = Instant.now(); - long duration; + Duration to = Duration.ofMillis(timeout); + Duration now = Duration.ofNanos(System.nanoTime()); + Duration duration; while ((obj = rdp (key)) == null && - (duration = Duration.between(now, Instant.now()).toMillis()) < timeout) + to.compareTo(duration = Duration.ofNanos(System.nanoTime()).minus(now)) > 0) { try { - this.wait (timeout - duration); + this.wait (Math.max(to.minus(duration).toMillis(), 1L)); } catch (InterruptedException e) { } } return (V) obj; @@ -163,13 +165,14 @@ public synchronized void nrd (Object key) { @Override public synchronized V nrd (Object key, long timeout) { Object obj; - Instant now = Instant.now(); - long duration; + Duration to = Duration.ofMillis(timeout); + Duration now = Duration.ofNanos(System.nanoTime()); + Duration duration; while ((obj = rdp (key)) != null && - (duration = Duration.between(now, Instant.now()).toMillis()) < timeout) + to.compareTo(duration = Duration.ofNanos(System.nanoTime()).minus(now)) > 0) { try { - this.wait (Math.min(NRD_RESOLUTION, timeout - duration)); + this.wait (Math.min(NRD_RESOLUTION, Math.max(to.minus(duration).toMillis(), 1L))); } catch (InterruptedException ignored) { } } return (V) obj; @@ -186,9 +189,9 @@ public void run () { public void gc () { gc(0); - if (Instant.now().toEpochMilli() - lastLongGC > GCLONG) { + if (Duration.ofMillis(GCLONG).compareTo(Duration.ofNanos(System.nanoTime()).minus(lastLongGC)) > 0) { gc(1); - lastLongGC = Instant.now().toEpochMilli(); + lastLongGC = Duration.ofNanos(System.nanoTime()); } } @@ -336,7 +339,7 @@ public void push (K key, V value, long timeout) { throw new NullPointerException ("key=" + key + ", value=" + value); Object v = value; if (timeout > 0) { - v = new Expirable (value, Instant.now().toEpochMilli() + timeout); + v = new Expirable (value, Duration.ofNanos(System.nanoTime()).plus(Duration.ofMillis(timeout))); } synchronized (this) { List l = getList(key); @@ -373,7 +376,7 @@ public void put (K key, V value, long timeout) { throw new NullPointerException ("key=" + key + ", value=" + value); Object v = value; if (timeout > 0) { - v = new Expirable (value, Instant.now().toEpochMilli() + timeout); + v = new Expirable (value, Duration.ofNanos(System.nanoTime()).plus(Duration.ofMillis(timeout))); } synchronized (this) { List l = new LinkedList(); @@ -399,14 +402,15 @@ public boolean existAny (K[] keys) { @Override public boolean existAny (K[] keys, long timeout) { - Instant now = Instant.now(); - long duration; - while ((duration = Duration.between(now, Instant.now()).toMillis()) < timeout) { + Duration to = Duration.ofMillis(timeout); + Duration now = Duration.ofNanos(System.nanoTime()); + Duration duration; + while (to.compareTo(duration = Duration.ofNanos(System.nanoTime()).minus(now)) > 0) { if (existAny (keys)) return true; synchronized (this) { try { - wait (timeout - duration); + wait (Math.max(to.minus(duration).toMillis(), 1L)); } catch (InterruptedException e) { } } } @@ -520,16 +524,16 @@ static class Expirable implements Comparable, Serializable { static final long serialVersionUID = 0xA7F22BF5; Object value; - long expires; + Duration expires; - public Expirable (Object value, long expires) { + public Expirable (Object value, Duration expires) { super(); this.value = value; this.expires = expires; } public boolean isExpired () { - return expires < Instant.now().toEpochMilli(); + return expires.compareTo(Duration.ofNanos(System.nanoTime())) < 0; } @Override @@ -547,10 +551,10 @@ public Object getValue() { @Override public int compareTo (Object obj) { Expirable other = (Expirable) obj; - long otherExpires = other.expires; - if (otherExpires == expires) + Duration otherExpires = other.expires; + if (otherExpires.equals(expires)) return 0; - else if (expires < otherExpires) + else if (expires.compareTo(otherExpires) < 0) return -1; else return 1; diff --git a/jpos/src/test/java/org/jpos/space/TSpacePerformanceTest.java b/jpos/src/test/java/org/jpos/space/TSpacePerformanceTest.java index 0c096d2adc..86b4fe77b3 100644 --- a/jpos/src/test/java/org/jpos/space/TSpacePerformanceTest.java +++ b/jpos/src/test/java/org/jpos/space/TSpacePerformanceTest.java @@ -19,7 +19,6 @@ package org.jpos.space; import java.time.Duration; -import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; @@ -184,9 +183,9 @@ public void testDeadLockWithNotify() throws Throwable { for (int i=0; i 0) { - if (Duration.between(stamp, Instant.now()).toMillis() < 10000){ + if (Duration.ofNanos(System.nanoTime()).minus(stamp).toMillis() < 10000){ ISOUtil.sleep(100); continue; } diff --git a/jpos/src/test/java/org/jpos/space/TSpaceTest.java b/jpos/src/test/java/org/jpos/space/TSpaceTest.java index 1522676459..4ddf9aaf5c 100644 --- a/jpos/src/test/java/org/jpos/space/TSpaceTest.java +++ b/jpos/src/test/java/org/jpos/space/TSpaceTest.java @@ -29,6 +29,7 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.time.Duration; import java.util.AbstractSet; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -62,27 +63,27 @@ public void testDump() throws Throwable { @Test public void testExpirableCompareTo() throws Throwable { - int result = new TSpace.Expirable(Integer.valueOf(0), 1L).compareTo(new TSpace.Expirable(new Object(), 0L)); + int result = new TSpace.Expirable(Integer.valueOf(0), Duration.ofMillis(1L)).compareTo(new TSpace.Expirable(new Object(), Duration.ofMillis(0L))); assertEquals(1, result, "result"); } @Test public void testExpirableCompareTo1() throws Throwable { - TSpace.Expirable obj = new TSpace.Expirable(new Object(), 0L); - int result = new TSpace.Expirable(new Object(), 0L).compareTo(obj); + TSpace.Expirable obj = new TSpace.Expirable(new Object(), Duration.ofMillis(0L)); + int result = new TSpace.Expirable(new Object(), Duration.ofMillis(0L)).compareTo(obj); assertEquals(0, result, "result"); } @Test public void testExpirableCompareTo2() throws Throwable { - int result = new TSpace.Expirable(null, 0L).compareTo(new TSpace.Expirable(new Object(), 1L)); + int result = new TSpace.Expirable(null, Duration.ofMillis(0L)).compareTo(new TSpace.Expirable(new Object(), Duration.ofMillis(1L))); assertEquals(-1, result, "result"); } @Test public void testExpirableCompareToThrowsNullPointerException() throws Throwable { try { - new TSpace.Expirable(new Object(), 100L).compareTo(null); + new TSpace.Expirable(new Object(), Duration.ofMillis(100L)).compareTo(null); fail("Expected NullPointerException to be thrown"); } catch (NullPointerException ex) { if (isJavaVersionAtMost(JAVA_14)) { @@ -96,51 +97,51 @@ public void testExpirableCompareToThrowsNullPointerException() throws Throwable @Test public void testExpirableConstructor() throws Throwable { Object value = new Object(); - TSpace.Expirable expirable = new TSpace.Expirable(value, 100L); - assertEquals(100L, expirable.expires, "expirable.expires"); + TSpace.Expirable expirable = new TSpace.Expirable(value, Duration.ofMillis(100L)); + assertEquals(Duration.ofMillis(100L), expirable.expires, "expirable.expires"); assertSame(value, expirable.value, "expirable.value"); } @Test public void testExpirableGetValue() throws Throwable { - String result = (String) new TSpace.Expirable("", 9184833384926L).getValue(); + String result = (String) new TSpace.Expirable("", Duration.ofNanos(System.nanoTime()).plus(Duration.ofMillis(9184833384926L))).getValue(); assertEquals("", result, "result"); } @Test public void testExpirableGetValue1() throws Throwable { - Object result = new TSpace.Expirable(null, 9184833384926L).getValue(); + Object result = new TSpace.Expirable(null, Duration.ofMillis(9184833384926L)).getValue(); assertNull(result, "result"); } @Test public void testExpirableGetValue2() throws Throwable { - Object result = new TSpace.Expirable(new Object(), 100L).getValue(); + Object result = new TSpace.Expirable(new Object(), Duration.ofNanos(System.nanoTime()).minus(Duration.ofMillis(100L))).getValue(); assertNull(result, "result"); } @Test public void testExpirableIsExpired() throws Throwable { - boolean result = new TSpace.Expirable("", 9184833384926L).isExpired(); + boolean result = new TSpace.Expirable("", Duration.ofNanos(System.nanoTime()).plus(Duration.ofMillis(9184833384926L))).isExpired(); assertFalse(result, "result"); } @Test public void testExpirableIsExpired1() throws Throwable { - boolean result = new TSpace.Expirable(new Object(), 100L).isExpired(); + boolean result = new TSpace.Expirable(new Object(), Duration.ofNanos(System.nanoTime()).minus(Duration.ofMillis(100L))).isExpired(); assertTrue(result, "result"); } @Test public void testExpirableToString() throws Throwable { - new TSpace.Expirable(";\"i", 100L).toString(); + new TSpace.Expirable(";\"i", Duration.ofMillis(100L)).toString(); assertTrue(true, "Test completed without Exception"); } @Test public void testExpirableToStringThrowsNullPointerException() throws Throwable { try { - new TSpace.Expirable(null, 100L).toString(); + new TSpace.Expirable(null, Duration.ofMillis(100L)).toString(); fail("Expected NullPointerException to be thrown"); } catch (NullPointerException ex) { if (isJavaVersionAtMost(JAVA_14)) { diff --git a/jpos/src/test/java/org/jpos/space/TSpaceTestCase.java b/jpos/src/test/java/org/jpos/space/TSpaceTestCase.java index 9ecee24c0b..3b9cf00f4d 100644 --- a/jpos/src/test/java/org/jpos/space/TSpaceTestCase.java +++ b/jpos/src/test/java/org/jpos/space/TSpaceTestCase.java @@ -19,7 +19,6 @@ package org.jpos.space; import java.time.Duration; -import java.time.Instant; import java.util.HashSet; import java.util.Set; @@ -289,28 +288,28 @@ public void run() { sp.out("KA", Boolean.TRUE); } }.start(); - Instant now = Instant.now(); + Duration now = Duration.ofNanos(System.nanoTime()); assertTrue(sp.existAny(new String[] { "KA", "KB" }, 2000L), "existAnyWithTimeout ([KA,KB], delay)"); - long elapsed = Duration.between(now, Instant.now()).toMillis(); + long elapsed = Duration.ofNanos(System.nanoTime()).minus(now).toMillis(); assertTrue(elapsed > 900L, "delay was > 1000"); } @Test public void testNRD() { - Instant now = Instant.now(); + Duration now = Duration.ofNanos(System.nanoTime()); sp.out("NRD", "NRDTEST", 1000L); sp.nrd("NRD"); - long elapsed = Duration.between(now, Instant.now()).toMillis(); + long elapsed = Duration.ofNanos(System.nanoTime()).minus(now).toMillis(); assertTrue(elapsed >= 1000L, "Invalid elapsed time " + elapsed); } @Test public void testNRDWithDelay() { - Instant now = Instant.now(); + Duration now = Duration.ofNanos(System.nanoTime()); sp.out("NRD", "NRDTEST", 1000L); Object obj = sp.nrd("NRD", 500L); assertNotNull(obj, "Object should not be null"); obj = sp.nrd("NRD", 5000L); - long elapsed = Duration.between(now, Instant.now()).toMillis(); + long elapsed = Duration.ofNanos(System.nanoTime()).minus(now).toMillis(); assertTrue(elapsed >= 1000L && elapsed <= 2000L, "Invalid elapsed time " + elapsed); assertNull(obj, "Object should be null"); } From dcad985042390098b35b056779a27a7c8f9ec55c Mon Sep 17 00:00:00 2001 From: Barzilai Spinak Date: Fri, 24 Nov 2023 00:29:05 -0300 Subject: [PATCH 2/2] TSpace: simplifying usage of monotonic nanoTime() --- jpos/src/main/java/org/jpos/space/TSpace.java | 108 +++++++++--------- .../test/java/org/jpos/space/TSpaceTest.java | 43 +++---- 2 files changed, 77 insertions(+), 74 deletions(-) diff --git a/jpos/src/main/java/org/jpos/space/TSpace.java b/jpos/src/main/java/org/jpos/space/TSpace.java index 14ef344d90..955af6cb49 100644 --- a/jpos/src/main/java/org/jpos/space/TSpace.java +++ b/jpos/src/main/java/org/jpos/space/TSpace.java @@ -1,6 +1,6 @@ /* * jPOS Project [http://jpos.org] - * Copyright (C) 2000-2021 jPOS Software SRL + * Copyright (C) 2000-2023 jPOS Software SRL * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -17,11 +17,10 @@ */ package org.jpos.space; -import org.jpos.util.Loggeable; +import org.jpos.util.Loggeable; import java.io.PrintStream; import java.io.Serializable; -import java.time.Duration; import java.util.*; import java.util.concurrent.TimeUnit; @@ -40,8 +39,9 @@ public class TSpace implements LocalSpace, Loggeable, Runnable { private static final long GCLONG = 60*1000; private static final long NRD_RESOLUTION = 500L; private static final int MAX_ENTRIES_IN_DUMP = 1000; + private static final long ONE_MILLION = 1_000_000L; // multiplier millis --> nanos private final Set[] expirables; - private Duration lastLongGC = Duration.ofNanos(System.nanoTime()); + private long lastLongGC = System.nanoTime(); public TSpace () { super(); @@ -70,7 +70,7 @@ public void out (K key, V value, long timeout) { throw new NullPointerException ("key=" + key + ", value=" + value); Object v = value; if (timeout > 0) { - v = new Expirable (value, Duration.ofNanos(System.nanoTime()).plus(Duration.ofMillis(timeout))); + v = new Expirable (value, System.nanoTime() + (timeout * ONE_MILLION)); } synchronized (this) { List l = getList(key); @@ -112,18 +112,18 @@ public synchronized V in (Object key) { @Override public synchronized V in (Object key, long timeout) { - Object obj; - Duration to = Duration.ofMillis(timeout); - Duration now = Duration.ofNanos(System.nanoTime()); - Duration duration; - while ((obj = inp (key)) == null && - to.compareTo(duration = Duration.ofNanos(System.nanoTime()).minus(now)) > 0) + V obj; + long now = System.nanoTime(); + long to = now + timeout * ONE_MILLION; + long waitFor; + while ( (obj = inp (key)) == null && + (waitFor = (to - System.nanoTime())) >= 0 ) { try { - this.wait (Math.max(to.minus(duration).toMillis(), 1L)); + this.wait(Math.max(waitFor / ONE_MILLION, 1L)); } catch (InterruptedException e) { } } - return (V) obj; + return obj; } @Override @@ -139,18 +139,18 @@ public synchronized V rd (Object key) { @Override public synchronized V rd (Object key, long timeout) { - Object obj; - Duration to = Duration.ofMillis(timeout); - Duration now = Duration.ofNanos(System.nanoTime()); - Duration duration; - while ((obj = rdp (key)) == null && - to.compareTo(duration = Duration.ofNanos(System.nanoTime()).minus(now)) > 0) + V obj; + long now = System.nanoTime(); + long to = now + (timeout * ONE_MILLION); + long waitFor; + while ( (obj = rdp (key)) == null && + (waitFor = (to - System.nanoTime())) >= 0 ) { try { - this.wait (Math.max(to.minus(duration).toMillis(), 1L)); + this.wait(Math.max(waitFor / ONE_MILLION, 1L)); } catch (InterruptedException e) { } } - return (V) obj; + return obj; } @Override @@ -164,18 +164,19 @@ public synchronized void nrd (Object key) { @Override public synchronized V nrd (Object key, long timeout) { - Object obj; - Duration to = Duration.ofMillis(timeout); - Duration now = Duration.ofNanos(System.nanoTime()); - Duration duration; - while ((obj = rdp (key)) != null && - to.compareTo(duration = Duration.ofNanos(System.nanoTime()).minus(now)) > 0) + V obj; + long now = System.nanoTime(); + long to = now + (timeout * ONE_MILLION); + long waitFor; + while ( (obj = rdp (key)) != null && + (waitFor = (to - System.nanoTime())) >= 0 ) { try { - this.wait (Math.min(NRD_RESOLUTION, Math.max(to.minus(duration).toMillis(), 1L))); + this.wait(Math.min(NRD_RESOLUTION, + Math.max(waitFor / ONE_MILLION, 1L))); } catch (InterruptedException ignored) { } } - return (V) obj; + return obj; } @Override @@ -189,9 +190,9 @@ public void run () { public void gc () { gc(0); - if (Duration.ofMillis(GCLONG).compareTo(Duration.ofNanos(System.nanoTime()).minus(lastLongGC)) > 0) { + if (System.nanoTime() - lastLongGC > GCLONG) { gc(1); - lastLongGC = Duration.ofNanos(System.nanoTime()); + lastLongGC = System.nanoTime(); } } @@ -339,7 +340,7 @@ public void push (K key, V value, long timeout) { throw new NullPointerException ("key=" + key + ", value=" + value); Object v = value; if (timeout > 0) { - v = new Expirable (value, Duration.ofNanos(System.nanoTime()).plus(Duration.ofMillis(timeout))); + v = new Expirable (value, System.nanoTime() + (timeout * ONE_MILLION)); } synchronized (this) { List l = getList(key); @@ -376,7 +377,7 @@ public void put (K key, V value, long timeout) { throw new NullPointerException ("key=" + key + ", value=" + value); Object v = value; if (timeout > 0) { - v = new Expirable (value, Duration.ofNanos(System.nanoTime()).plus(Duration.ofMillis(timeout))); + v = new Expirable (value, System.nanoTime() + (timeout * ONE_MILLION)); } synchronized (this) { List l = new LinkedList(); @@ -402,15 +403,15 @@ public boolean existAny (K[] keys) { @Override public boolean existAny (K[] keys, long timeout) { - Duration to = Duration.ofMillis(timeout); - Duration now = Duration.ofNanos(System.nanoTime()); - Duration duration; - while (to.compareTo(duration = Duration.ofNanos(System.nanoTime()).minus(now)) > 0) { + long now = System.nanoTime(); + long to = now + (timeout * ONE_MILLION); + long waitFor; + while ((waitFor = (to - System.nanoTime())) >= 0) { if (existAny (keys)) return true; synchronized (this) { try { - wait (Math.max(to.minus(duration).toMillis(), 1L)); + this.wait(Math.max(waitFor / ONE_MILLION, 1L)); } catch (InterruptedException e) { } } } @@ -521,19 +522,24 @@ private void unregisterExpirable(Object k) { static class Expirable implements Comparable, Serializable { - static final long serialVersionUID = 0xA7F22BF5; + private static final long serialVersionUID = 0xA7F22BF5; Object value; - Duration expires; - public Expirable (Object value, Duration expires) { + /** + * When to expire, in the future, as given by monotonic System.nanoTime().
+ * IMPORTANT: always use a nanosec offset from System.nanoTime()! + */ + long expires; + + Expirable (Object value, long expires) { super(); this.value = value; this.expires = expires; } - public boolean isExpired () { - return expires.compareTo(Duration.ofNanos(System.nanoTime())) < 0; + boolean isExpired () { + return (System.nanoTime() - expires) > 0; } @Override @@ -544,20 +550,16 @@ public String toString() { + ",expired=" + isExpired (); } - public Object getValue() { + Object getValue() { return isExpired() ? null : value; } @Override - public int compareTo (Object obj) { - Expirable other = (Expirable) obj; - Duration otherExpires = other.expires; - if (otherExpires.equals(expires)) - return 0; - else if (expires.compareTo(otherExpires) < 0) - return -1; - else - return 1; + public int compareTo (Object other) { + long diff = this.expires - ((Expirable)other).expires; + return diff > 0 ? 1 : + diff < 0 ? -1 : + 0; } } diff --git a/jpos/src/test/java/org/jpos/space/TSpaceTest.java b/jpos/src/test/java/org/jpos/space/TSpaceTest.java index 4ddf9aaf5c..61a66ceb89 100644 --- a/jpos/src/test/java/org/jpos/space/TSpaceTest.java +++ b/jpos/src/test/java/org/jpos/space/TSpaceTest.java @@ -43,6 +43,7 @@ @SuppressWarnings("unchecked") @ExtendWith(MockitoExtension.class) public class TSpaceTest { + static final long EXPIRE_OFFSET = Duration.ofDays(9999).toNanos(); @Test public void testConstructor() throws Throwable { @@ -63,27 +64,27 @@ public void testDump() throws Throwable { @Test public void testExpirableCompareTo() throws Throwable { - int result = new TSpace.Expirable(Integer.valueOf(0), Duration.ofMillis(1L)).compareTo(new TSpace.Expirable(new Object(), Duration.ofMillis(0L))); + int result = new TSpace.Expirable(Integer.valueOf(0), 1L).compareTo(new TSpace.Expirable(new Object(), 0L)); assertEquals(1, result, "result"); } @Test public void testExpirableCompareTo1() throws Throwable { - TSpace.Expirable obj = new TSpace.Expirable(new Object(), Duration.ofMillis(0L)); - int result = new TSpace.Expirable(new Object(), Duration.ofMillis(0L)).compareTo(obj); + TSpace.Expirable obj = new TSpace.Expirable(new Object(), 0L); + int result = new TSpace.Expirable(new Object(), 0L).compareTo(obj); assertEquals(0, result, "result"); } @Test public void testExpirableCompareTo2() throws Throwable { - int result = new TSpace.Expirable(null, Duration.ofMillis(0L)).compareTo(new TSpace.Expirable(new Object(), Duration.ofMillis(1L))); + int result = new TSpace.Expirable(null, 0L).compareTo(new TSpace.Expirable(new Object(), 1L)); assertEquals(-1, result, "result"); } @Test public void testExpirableCompareToThrowsNullPointerException() throws Throwable { try { - new TSpace.Expirable(new Object(), Duration.ofMillis(100L)).compareTo(null); + new TSpace.Expirable(new Object(), 100L).compareTo(null); fail("Expected NullPointerException to be thrown"); } catch (NullPointerException ex) { if (isJavaVersionAtMost(JAVA_14)) { @@ -97,51 +98,53 @@ public void testExpirableCompareToThrowsNullPointerException() throws Throwable @Test public void testExpirableConstructor() throws Throwable { Object value = new Object(); - TSpace.Expirable expirable = new TSpace.Expirable(value, Duration.ofMillis(100L)); - assertEquals(Duration.ofMillis(100L), expirable.expires, "expirable.expires"); + TSpace.Expirable expirable = new TSpace.Expirable(value, 100L); + assertEquals(100L, expirable.expires, "expirable.expires"); assertSame(value, expirable.value, "expirable.value"); } @Test public void testExpirableGetValue() throws Throwable { - String result = (String) new TSpace.Expirable("", Duration.ofNanos(System.nanoTime()).plus(Duration.ofMillis(9184833384926L))).getValue(); + String result = (String) new TSpace.Expirable("", System.nanoTime() + EXPIRE_OFFSET).getValue(); assertEquals("", result, "result"); } @Test public void testExpirableGetValue1() throws Throwable { - Object result = new TSpace.Expirable(null, Duration.ofMillis(9184833384926L)).getValue(); + Object result = new TSpace.Expirable(null, System.nanoTime() + EXPIRE_OFFSET).getValue(); assertNull(result, "result"); } @Test public void testExpirableGetValue2() throws Throwable { - Object result = new TSpace.Expirable(new Object(), Duration.ofNanos(System.nanoTime()).minus(Duration.ofMillis(100L))).getValue(); + // using negative offset to ensure expiration (literally, object is born already expired) + Object result = new TSpace.Expirable(new Object(), System.nanoTime() - EXPIRE_OFFSET).getValue(); assertNull(result, "result"); } @Test public void testExpirableIsExpired() throws Throwable { - boolean result = new TSpace.Expirable("", Duration.ofNanos(System.nanoTime()).plus(Duration.ofMillis(9184833384926L))).isExpired(); + boolean result = new TSpace.Expirable("", System.nanoTime() + EXPIRE_OFFSET).isExpired(); assertFalse(result, "result"); } @Test public void testExpirableIsExpired1() throws Throwable { - boolean result = new TSpace.Expirable(new Object(), Duration.ofNanos(System.nanoTime()).minus(Duration.ofMillis(100L))).isExpired(); + // using negative offset to ensure expiration (literally, object is born already expired) + boolean result = new TSpace.Expirable(new Object(), System.nanoTime() - EXPIRE_OFFSET).isExpired(); assertTrue(result, "result"); } @Test public void testExpirableToString() throws Throwable { - new TSpace.Expirable(";\"i", Duration.ofMillis(100L)).toString(); + new TSpace.Expirable(";\"i", 100L).toString(); assertTrue(true, "Test completed without Exception"); } @Test public void testExpirableToStringThrowsNullPointerException() throws Throwable { try { - new TSpace.Expirable(null, Duration.ofMillis(100L)).toString(); + new TSpace.Expirable(null,100L).toString(); fail("Expected NullPointerException to be thrown"); } catch (NullPointerException ex) { if (isJavaVersionAtMost(JAVA_14)) { @@ -154,7 +157,6 @@ public void testExpirableToStringThrowsNullPointerException() throws Throwable { @Test public void testGc() throws Throwable { - TSpace tSpace = new TSpace(); tSpace.gc(); assertEquals(0, tSpace.entries.size(), "tSpace.entries.size()"); @@ -208,6 +210,7 @@ public void testInp1() throws Throwable { "tSpace.entries.get(\"\").get(0) had \"testString\" removed"); assertEquals("testString", result, "result"); assertEquals(3, tSpace.entries.size(), "tSpace.entries.size()"); + tSpace.dump(System.out, ">>"); } @Test @@ -240,12 +243,10 @@ public void testNotifyReaders() { final Space sp = new TSpace(); final AtomicInteger ai = new AtomicInteger(10); for (int i=0; i<10; i++) { - new Thread() { - public void run() { - if (sp.rd("TEST", 5000L) != null) - ai.decrementAndGet(); - } - }.start(); + new Thread(()->{ + if (sp.rd("TEST", 5000L) != null) + ai.decrementAndGet(); + }).start(); } sp.out("TEST", Boolean.TRUE); ISOUtil.sleep(500L);