Skip to content

Commit

Permalink
- Added the SealableXXX collection classes.
Browse files Browse the repository at this point in the history
- Strengthened the implementation of ConcurrentList and ConcurrentHashSet.
- Renamed ConcurrentHashSet to ConcurrentSet
  • Loading branch information
jdereg committed Apr 29, 2024
1 parent f3ec068 commit bc1d644
Show file tree
Hide file tree
Showing 14 changed files with 318 additions and 263 deletions.
6 changes: 4 additions & 2 deletions src/main/java/com/cedarsoftware/util/CaseInsensitiveMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@
* entrySet() APIs return the original Strings, not the internally
* wrapped CaseInsensitiveString.
*
* As an added benefit, .keySet() returns a case-insenstive
* As an added benefit, .keySet() returns a case-insensitive
* Set, however, again, the contents of the entries are actual Strings.
* Similarly, .entrySet() returns a case-insensitive entry set, such that
* .getKey() on the entry is case insensitive when compared, but the
* .getKey() on the entry is case-insensitive when compared, but the
* returned key is a String.
*
* @author John DeRegnaucourt ([email protected])
Expand Down Expand Up @@ -314,11 +314,13 @@ public Collection<V> values()
return map.values();
}

@Deprecated
public Map minus(Object removeMe)
{
throw new UnsupportedOperationException("Unsupported operation [minus] or [-] between Maps. Use removeAll() or retainAll() instead.");
}

@Deprecated
public Map plus(Object right)
{
throw new UnsupportedOperationException("Unsupported operation [plus] or [+] between Maps. Use putAll() instead.");
Expand Down
24 changes: 14 additions & 10 deletions src/main/java/com/cedarsoftware/util/CaseInsensitiveSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class CaseInsensitiveSet<E> implements Set<E>

public CaseInsensitiveSet(Collection<? extends E> collection)
{
if (collection instanceof ConcurrentSkipListSet || collection instanceof ConcurrentHashSet)
if (collection instanceof ConcurrentSkipListSet || collection instanceof ConcurrentSet)
{
map = new CaseInsensitiveMap<>(new ConcurrentSkipListMap<>());
}
Expand Down Expand Up @@ -98,7 +98,7 @@ public boolean equals(Object other)
if (other == this) return true;
if (!(other instanceof Set)) return false;

Set that = (Set) other;
Set<E> that = (Set<E>) other;
return that.size()==size() && containsAll(that);
}

Expand Down Expand Up @@ -176,7 +176,7 @@ public boolean retainAll(Collection<?> c)
other.put(o, null);
}

Iterator i = map.keySet().iterator();
Iterator<?> i = map.keySet().iterator();
int size = map.size();
while (i.hasNext())
{
Expand Down Expand Up @@ -204,7 +204,8 @@ public void clear()
map.clear();
}

public Set minus(Iterable removeMe)
@Deprecated
public Set<E> minus(Iterable<E> removeMe)
{
for (Object me : removeMe)
{
Expand All @@ -213,22 +214,25 @@ public Set minus(Iterable removeMe)
return this;
}

public Set minus(Object removeMe)
@Deprecated
public Set<E> minus(E removeMe)
{
remove(removeMe);
return this;
}

public Set plus(Iterable right)

@Deprecated
public Set<E> plus(Iterable<E> right)
{
for (Object item : right)
for (E item : right)
{
add((E)item);
add(item);
}
return this;
}

public Set plus(Object right)
@Deprecated
public Set<E> plus(Object right)
{
add((E)right);
return this;
Expand Down
79 changes: 0 additions & 79 deletions src/main/java/com/cedarsoftware/util/ConcurrentHashSet.java

This file was deleted.

119 changes: 33 additions & 86 deletions src/main/java/com/cedarsoftware/util/ConcurrentList.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
* ConcurrentList provides a List or List wrapper that is thread-safe, usable in highly concurrent
* ConcurrentList provides a List and List wrapper that is thread-safe, usable in highly concurrent
* environments. It provides a no-arg constructor that will directly return a ConcurrentList that is
* thread-safe. It has a constructor that takes a List argument, which will wrap that List and make it
* thread-safe (no elements are duplicated).
* thread-safe (no elements are duplicated).<br>
* <br>
* The iterator(), listIterator() return read-only views copied from the list. The listIterator(index)
* is not implemented, as the inbound index could already be outside the lists position due to concurrent
* edits. Similarly, subList(from, to) is not implemented because the boundaries may exceed the lists
* size due to concurrent edits.
* <br><br>
* @author John DeRegnaucourt ([email protected])
* <br>
Expand All @@ -32,12 +38,13 @@
*/
public class ConcurrentList<E> implements List<E> {
private final List<E> list;
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final ReadWriteLock lock;

/**
* Use this no-arg constructor to create a ConcurrentList.
*/
public ConcurrentList() {
lock = new ReentrantReadWriteLock();
this.list = new ArrayList<>();
}

Expand All @@ -50,6 +57,7 @@ public ConcurrentList(List<E> list) {
if (list == null) {
throw new IllegalArgumentException("list cannot be null");
}
lock = new ReentrantReadWriteLock();
this.list = list;
}

Expand Down Expand Up @@ -89,6 +97,15 @@ public int hashCode() {
}
}

public String toString() {
lock.readLock().lock();
try {
return list.toString();
} finally {
lock.readLock().unlock();
}
}

public boolean contains(Object o) {
lock.readLock().lock();
try {
Expand All @@ -101,7 +118,7 @@ public boolean contains(Object o) {
public Iterator<E> iterator() {
lock.readLock().lock();
try {
return new ArrayList<>(list).iterator(); // Create a snapshot for iterator
return new ArrayList<>(list).iterator();
} finally {
lock.readLock().unlock();
}
Expand Down Expand Up @@ -146,7 +163,7 @@ public boolean remove(Object o) {
public boolean containsAll(Collection<?> c) {
lock.readLock().lock();
try {
return list.containsAll(c);
return new HashSet<>(list).containsAll(c);
} finally {
lock.readLock().unlock();
}
Expand Down Expand Up @@ -251,90 +268,20 @@ public int lastIndexOf(Object o) {
}
}

public List<E> subList(int fromIndex, int toIndex) { return new ConcurrentList<>(list.subList(fromIndex, toIndex)); }
public List<E> subList(int fromIndex, int toIndex) {
throw new UnsupportedOperationException("subList not implemented for ConcurrentList");
}

public ListIterator<E> listIterator() {
return createLockHonoringListIterator(list.listIterator());
lock.readLock().lock();
try {
return new ArrayList<E>(list).listIterator();
} finally {
lock.readLock().unlock();
}
}

public ListIterator<E> listIterator(int index) {
return createLockHonoringListIterator(list.listIterator(index));
}

private ListIterator<E> createLockHonoringListIterator(ListIterator<E> iterator) {
return new ListIterator<E>() {
public boolean hasNext() {
lock.readLock().lock();
try {
return iterator.hasNext();
} finally {
lock.readLock().unlock();
}
}
public E next() {
lock.readLock().lock();
try {
return iterator.next();
} finally {
lock.readLock().unlock();
}
}
public boolean hasPrevious() {
lock.readLock().lock();
try {
return iterator.hasPrevious();
} finally {
lock.readLock().unlock();
}
}
public E previous() {
lock.readLock().lock();
try {
return iterator.previous();
} finally {
lock.readLock().unlock();
}
}
public int nextIndex() {
lock.readLock().lock();
try {
return iterator.nextIndex();
} finally {
lock.readLock().unlock();
}
}
public int previousIndex() {
lock.readLock().lock();
try {
return iterator.previousIndex();
} finally {
lock.readLock().unlock();
}
}
public void remove() {
lock.writeLock().lock();
try {
iterator.remove();
} finally {
lock.writeLock().unlock();
}
}
public void set(E e) {
lock.writeLock().lock();
try {
iterator.set(e);
} finally {
lock.writeLock().unlock();
}
}
public void add(E e) {
lock.writeLock().lock();
try {
iterator.add(e);
} finally {
lock.writeLock().unlock();
}
}
};
throw new UnsupportedOperationException("listIterator(index) not implemented for ConcurrentList");
}
}
}
Loading

0 comments on commit bc1d644

Please sign in to comment.