0
# Collections Utilities
1
2
Apache ActiveMQ Artemis Commons provides specialized collection implementations optimized for high-performance messaging workloads. These collections focus on concurrency, memory efficiency, and type safety for primitive types.
3
4
## Capabilities
5
6
### Concurrent Collections
7
8
High-performance concurrent collections that avoid locking overhead and support lock-free operations.
9
10
#### ConcurrentHashSet
11
12
Thread-safe hash set implementation with the same concurrency characteristics as ConcurrentHashMap.
13
14
```java { .api }
15
class ConcurrentHashSet<E> extends AbstractSet<E> implements ConcurrentSet<E> {
16
// Constructor
17
ConcurrentHashSet();
18
19
// Set operations
20
boolean add(E o);
21
boolean contains(Object o);
22
boolean remove(Object o);
23
void clear();
24
25
// Concurrent-specific operations
26
boolean addIfAbsent(E o);
27
28
// Size and state
29
int size();
30
boolean isEmpty();
31
Iterator<E> iterator();
32
}
33
34
interface ConcurrentSet<E> extends Set<E> {
35
boolean addIfAbsent(E o);
36
}
37
```
38
39
#### ConcurrentLongHashMap
40
41
High-performance concurrent map from primitive long keys to Object values, avoiding boxing/unboxing overhead.
42
43
```java { .api }
44
class ConcurrentLongHashMap<V> {
45
// Constructors
46
ConcurrentLongHashMap();
47
ConcurrentLongHashMap(int expectedItems);
48
ConcurrentLongHashMap(int expectedItems, int numSections);
49
50
// Map operations
51
V get(long key);
52
V put(long key, V value);
53
V putIfAbsent(long key, V value);
54
V computeIfAbsent(long key, LongFunction<V> provider);
55
V remove(long key);
56
boolean remove(long key, Object value);
57
58
// Query operations
59
boolean containsKey(long key);
60
int size();
61
long capacity();
62
boolean isEmpty();
63
void clear();
64
65
// Iteration
66
void forEach(EntryProcessor<V> processor);
67
List<Long> keys();
68
ConcurrentLongHashSet keysLongHashSet();
69
List<V> values();
70
71
// Functional interface for iteration
72
interface EntryProcessor<V> {
73
void accept(long key, V value);
74
}
75
}
76
```
77
78
#### ConcurrentLongHashSet
79
80
Concurrent hash set for primitive longs with no boxing overhead. Items must be >= 0.
81
82
```java { .api }
83
class ConcurrentLongHashSet {
84
// Constructors
85
ConcurrentLongHashSet();
86
ConcurrentLongHashSet(int expectedItems);
87
ConcurrentLongHashSet(int expectedItems, int numSections);
88
89
// Set operations
90
boolean add(long item);
91
boolean contains(long item);
92
boolean remove(long item);
93
void clear();
94
95
// Query operations
96
int size();
97
long capacity();
98
boolean isEmpty();
99
100
// Iteration
101
void forEach(ConsumerLong processor);
102
Set<Long> items();
103
104
// Functional interface for iteration
105
interface ConsumerLong {
106
void accept(long item);
107
}
108
}
109
```
110
111
### Linked List Implementations
112
113
Custom linked list implementations supporting multiple concurrent iterators and efficient add/remove operations.
114
115
#### LinkedListImpl
116
117
Linked list supporting multiple concurrent iterators with direct element manipulation capabilities.
118
119
```java { .api }
120
class LinkedListImpl<E> implements LinkedList<E> {
121
// Constructors
122
LinkedListImpl();
123
LinkedListImpl(Comparator<E> comparator);
124
LinkedListImpl(Comparator<E> comparator, NodeStore<E> supplier);
125
126
// Add operations
127
void addHead(E e);
128
void addTail(E e);
129
void addSorted(E e); // Requires comparator
130
131
// Access operations
132
E get(int position);
133
E poll();
134
E peek();
135
136
// Iterator operations
137
LinkedListIterator<E> iterator();
138
int numIters();
139
140
// Management operations
141
void clear();
142
int size();
143
void clearID();
144
void setNodeStore(NodeStore<E> store);
145
E removeWithID(String listID, long id);
146
void forEach(Consumer<E> consumer);
147
148
// Inner node class
149
static class Node<E> {
150
protected E val();
151
protected Node<E> next();
152
protected Node<E> prev();
153
static <E> Node<E> with(E o);
154
}
155
156
// Enhanced iterator
157
class Iterator implements LinkedListIterator<E> {
158
void repeat();
159
boolean hasNext();
160
E next();
161
void remove();
162
E removeLastElement();
163
void close();
164
}
165
}
166
167
interface LinkedList<E> {
168
void addHead(E e);
169
void addTail(E e);
170
E get(int position);
171
E poll();
172
E peek();
173
LinkedListIterator<E> iterator();
174
void clear();
175
int size();
176
void clearID();
177
void setNodeStore(NodeStore<E> store);
178
E removeWithID(String listID, long id);
179
void forEach(Consumer<E> consumer);
180
}
181
182
interface LinkedListIterator<E> extends Iterator<E>, AutoCloseable {
183
void repeat();
184
E removeLastElement();
185
void close();
186
}
187
```
188
189
### Type-Safe Properties
190
191
Advanced property system with JMS-compliant type conversions and thread-safe operations.
192
193
#### TypedProperties
194
195
Property storage with type-safe conversions following JMS specification section 3.5.4.
196
197
```java { .api }
198
class TypedProperties {
199
// Constructors
200
TypedProperties();
201
TypedProperties(Predicate<SimpleString> internalPropertyPredicate);
202
TypedProperties(Predicate<SimpleString> internalPropertyPredicate,
203
Predicate<SimpleString> amqpPropertyPredicate);
204
TypedProperties(TypedProperties other); // Copy constructor
205
206
// Property setters
207
void putBooleanProperty(SimpleString key, boolean value);
208
void putByteProperty(SimpleString key, byte value);
209
void putBytesProperty(SimpleString key, byte[] value);
210
void putShortProperty(SimpleString key, short value);
211
void putIntProperty(SimpleString key, int value);
212
void putLongProperty(SimpleString key, long value);
213
void putFloatProperty(SimpleString key, float value);
214
void putDoubleProperty(SimpleString key, double value);
215
void putSimpleStringProperty(SimpleString key, SimpleString value);
216
void putCharProperty(SimpleString key, char value);
217
void putNullValue(SimpleString key);
218
TypedProperties putProperty(SimpleString key, Object value);
219
void putTypedProperties(TypedProperties otherProps);
220
221
// Property getters with type conversion
222
Object getProperty(SimpleString key);
223
Boolean getBooleanProperty(SimpleString key) throws ActiveMQPropertyConversionException;
224
Byte getByteProperty(SimpleString key) throws ActiveMQPropertyConversionException;
225
Byte getByteProperty(SimpleString key, Supplier<Byte> defaultValue)
226
throws ActiveMQPropertyConversionException;
227
Character getCharProperty(SimpleString key) throws ActiveMQPropertyConversionException;
228
byte[] getBytesProperty(SimpleString key) throws ActiveMQPropertyConversionException;
229
Double getDoubleProperty(SimpleString key) throws ActiveMQPropertyConversionException;
230
Integer getIntProperty(SimpleString key) throws ActiveMQPropertyConversionException;
231
Long getLongProperty(SimpleString key) throws ActiveMQPropertyConversionException;
232
Short getShortProperty(SimpleString key) throws ActiveMQPropertyConversionException;
233
Float getFloatProperty(SimpleString key) throws ActiveMQPropertyConversionException;
234
SimpleString getSimpleStringProperty(SimpleString key)
235
throws ActiveMQPropertyConversionException;
236
237
// Property management
238
Object removeProperty(SimpleString key);
239
boolean containsProperty(SimpleString key);
240
Set<SimpleString> getPropertyNames();
241
boolean clearInternalProperties();
242
boolean clearAMQPProperties();
243
244
// Size and state
245
int size();
246
int getMemoryOffset();
247
boolean isEmpty();
248
void clear();
249
250
// Iteration
251
void forEachKey(Consumer<SimpleString> action);
252
void forEach(BiConsumer<SimpleString, Object> action);
253
254
// Encoding/Decoding for serialization
255
void decode(ByteBuf buffer, TypedPropertiesDecoderPools keyValuePools);
256
void decode(ByteBuf buffer);
257
int encode(ByteBuf buffer);
258
int getEncodeSize();
259
260
// Thread safety
261
Lock getReadLock();
262
Lock getWriteLock();
263
264
// Utility methods
265
Set<String> getMapNames();
266
Map<String, Object> getMap();
267
268
// Static utility methods
269
static boolean searchProperty(SimpleString key, ByteBuf buffer, int startIndex);
270
static void setObjectProperty(SimpleString key, Object value, TypedProperties properties);
271
}
272
```
273
274
### Bounded Collections
275
276
Collections with automatic size management and memory-efficient implementations.
277
278
#### MaxSizeMap
279
280
LinkedHashMap that automatically removes eldest entries when size exceeds maximum.
281
282
```java { .api }
283
class MaxSizeMap<K, V> extends LinkedHashMap<K, V> {
284
// Constructor
285
MaxSizeMap(int maxSize);
286
287
// Inherits all LinkedHashMap methods
288
// Automatically removes eldest entries when maxSize is exceeded
289
}
290
```
291
292
## Usage Examples
293
294
### Concurrent Long Collections
295
296
```java
297
import org.apache.activemq.artemis.utils.collections.ConcurrentLongHashMap;
298
import org.apache.activemq.artemis.utils.collections.ConcurrentLongHashSet;
299
300
// Create concurrent map for message IDs to messages
301
ConcurrentLongHashMap<Message> messages = new ConcurrentLongHashMap<>(1000);
302
303
// Store messages by ID
304
long messageId = 12345L;
305
messages.put(messageId, message);
306
307
// Retrieve with no boxing overhead
308
Message retrievedMessage = messages.get(messageId);
309
310
// Atomic operations
311
Message existingMessage = messages.putIfAbsent(messageId, message);
312
313
// Compute if absent pattern
314
Message computedMessage = messages.computeIfAbsent(messageId, id -> createMessage(id));
315
316
// Iterate over entries
317
messages.forEach((id, msg) -> {
318
if (msg.isExpired()) {
319
messages.remove(id);
320
}
321
});
322
323
// Track processed message IDs
324
ConcurrentLongHashSet processedIds = new ConcurrentLongHashSet(500);
325
processedIds.add(messageId);
326
327
if (processedIds.contains(messageId)) {
328
// Skip duplicate processing
329
}
330
331
// Batch processing
332
processedIds.forEach(id -> {
333
// Process each ID
334
processMessage(id);
335
});
336
```
337
338
### LinkedList Operations
339
340
```java
341
import org.apache.activemq.artemis.utils.collections.LinkedListImpl;
342
import org.apache.activemq.artemis.utils.collections.LinkedListIterator;
343
344
// Create priority-ordered list
345
LinkedListImpl<Task> taskQueue = new LinkedListImpl<>(
346
Comparator.comparing(Task::getPriority).reversed()
347
);
348
349
// Add tasks
350
taskQueue.addSorted(new Task("high-priority", 10));
351
taskQueue.addTail(new Task("normal", 5));
352
taskQueue.addHead(new Task("urgent", 15));
353
354
// Process tasks in order
355
while (!taskQueue.isEmpty()) {
356
Task task = taskQueue.poll();
357
processTask(task);
358
}
359
360
// Use iterator for complex processing
361
try (LinkedListIterator<Task> iter = taskQueue.iterator()) {
362
while (iter.hasNext()) {
363
Task task = iter.next();
364
if (task.shouldBeRemoved()) {
365
iter.remove();
366
} else if (task.needsReprocessing()) {
367
iter.repeat(); // Process same element again
368
}
369
}
370
}
371
```
372
373
### Type-Safe Properties
374
375
```java
376
import org.apache.activemq.artemis.utils.collections.TypedProperties;
377
import org.apache.activemq.artemis.api.core.SimpleString;
378
379
// Create message properties
380
TypedProperties props = new TypedProperties();
381
382
// Set various property types
383
props.putStringProperty(SimpleString.of("userId"), "john.doe");
384
props.putIntProperty(SimpleString.of("priority"), 5);
385
props.putBooleanProperty(SimpleString.of("persistent"), true);
386
props.putLongProperty(SimpleString.of("timestamp"), System.currentTimeMillis());
387
388
// Type-safe retrieval with automatic conversion
389
try {
390
String userId = props.getSimpleStringProperty(SimpleString.of("userId")).toString();
391
Integer priority = props.getIntProperty(SimpleString.of("priority"));
392
Boolean persistent = props.getBooleanProperty(SimpleString.of("persistent"));
393
394
// JMS-compliant type conversions
395
String priorityAsString = props.getSimpleStringProperty(SimpleString.of("priority")).toString();
396
397
} catch (ActiveMQPropertyConversionException e) {
398
// Handle type conversion errors
399
logger.error("Property type conversion failed", e);
400
}
401
402
// Copy properties
403
TypedProperties copy = new TypedProperties(props);
404
405
// Merge properties
406
copy.putTypedProperties(additionalProps);
407
408
// Thread-safe operations
409
Lock readLock = props.getReadLock();
410
readLock.lock();
411
try {
412
// Read operations
413
Set<SimpleString> names = props.getPropertyNames();
414
} finally {
415
readLock.unlock();
416
}
417
```
418
419
### Bounded Collections
420
421
```java
422
import org.apache.activemq.artemis.utils.collections.MaxSizeMap;
423
424
// Create cache with automatic eviction
425
MaxSizeMap<String, CachedData> cache = new MaxSizeMap<>(1000);
426
427
// Add entries - oldest will be removed when size exceeds 1000
428
cache.put("key1", data1);
429
cache.put("key2", data2);
430
431
// Use as normal Map
432
CachedData retrieved = cache.get("key1");
433
boolean exists = cache.containsKey("key1");
434
435
// Cache automatically manages size
436
for (int i = 0; i < 2000; i++) {
437
cache.put("key" + i, createData(i));
438
}
439
// Cache size will never exceed 1000 entries
440
```
441
442
## Performance Characteristics
443
444
### ConcurrentLongHashMap/Set
445
- **Memory Efficient**: No boxing/unboxing of long keys
446
- **Concurrent**: Lock-free reads, segmented writes
447
- **Scalable**: Linear performance with number of threads
448
449
### LinkedListImpl
450
- **Iterator Safe**: Multiple concurrent iterators supported
451
- **Memory Efficient**: Node pooling and reuse
452
- **Flexible**: Direct node manipulation and sorted insertion
453
454
### TypedProperties
455
- **Type Safe**: JMS-compliant type conversions
456
- **Thread Safe**: Read/write locks for concurrent access
457
- **Serializable**: Efficient encode/decode for network transmission
458
459
These collections are optimized for ActiveMQ Artemis's messaging workloads where performance, memory efficiency, and thread safety are critical requirements.