SegmentIdTable { @NotNull synchronized SegmentId newSegmentId(long msb, long lsb, SegmentIdFactory maker) { int index = getIndex(lsb); boolean shouldRefresh = false; WeakReference<SegmentId> reference = references.get(index); while (reference != null) { SegmentId id = reference.get(); if (id != null && id.getMostSignificantBits() == msb && id.getLeastSignificantBits() == lsb) { return id; } shouldRefresh = shouldRefresh || id == null; index = (index + 1) % references.size(); reference = references.get(index); } SegmentId id = maker.newSegmentId(msb, lsb); references.set(index, new WeakReference<SegmentId>(id)); entryCount++; if (entryCount > references.size() * 0.75) { shouldRefresh = true; } if (shouldRefresh) { refresh(); } return id; }    }
@Test public void endlessSearchLoop() throws IOException { final SegmentIdFactory maker = newSegmentIdMaker(); final SegmentIdTable tbl = new SegmentIdTable(); List<SegmentId> refs = new ArrayList<SegmentId>(); for (int i = 0; i < 1024; i++) { refs.add(tbl.newSegmentId(i, i % 64, maker)); } Callable<SegmentId> c = new Callable<SegmentId>() { @Override public SegmentId call() throws Exception { return tbl.newSegmentId(2, 1, maker); } }; Future<SegmentId> f = Executors.newSingleThreadExecutor().submit(c); SegmentId s = null; try { s = f.get(5, TimeUnit.SECONDS); } catch (Exception e) { fail(e.getMessage()); } assertNotNull(s); assertEquals(2, s.getMostSignificantBits()); assertEquals(1, s.getLeastSignificantBits()); }