com.clickhouse.data.ClickHouseFreezableMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of clickhouse-data Show documentation
Show all versions of clickhouse-data Show documentation
Data processing utilities for ClickHouse
package com.clickhouse.data;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Freezable map. Once the map is freezed, all writes will be discarded without
* any error.
*/
public class ClickHouseFreezableMap implements Map {
/**
* Creates a freezable map with initial data and optional whitelisted keys.
*
* @param type of the key
* @param type of the value
* @param map non-null map with initial data
* @param whiteListedKeys optional whitelisted keys
* @return non-null freezable map
*/
public static ClickHouseFreezableMap of(Map map, K... whiteListedKeys) {
return new ClickHouseFreezableMap<>(ClickHouseChecker.nonNull(map, "Map"), whiteListedKeys);
}
private final AtomicBoolean freezed;
private final Map map;
private final List whitelist;
protected ClickHouseFreezableMap(Map map, K... keys) {
this.freezed = new AtomicBoolean(false);
this.map = map;
if (keys == null || keys.length == 0) {
this.whitelist = Collections.emptyList();
} else {
List list = new ArrayList<>(keys.length);
for (K k : keys) {
if (k != null && !list.contains(k)) {
list.add(k);
}
}
this.whitelist = Collections.unmodifiableList(list);
}
}
/**
* Checks whether the given key can be used in mutation(e.g. {@code put()},
* {@code remove()}), regardless the map is freezed or not.
*
* @param key non-null key
* @return true if the given key can be used in mutation; false otherwise
*/
protected boolean isMutable(Object key) {
return !freezed.get() || whitelist.contains(key);
}
@Override
public void clear() {
if (freezed.get()) {
for (K k : whitelist) {
map.remove(k);
}
} else {
map.clear();
}
}
@Override
public boolean containsKey(Object key) {
return map.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return map.containsValue(value);
}
@Override
public Set> entrySet() {
return map.entrySet();
}
@Override
public V get(Object key) {
return map.get(key);
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public Set keySet() {
return map.keySet();
}
@Override
public V put(K key, V value) {
return isMutable(key) ? map.put(key, value) : value;
}
@Override
public void putAll(Map extends K, ? extends V> m) {
if (freezed.get()) {
for (K k : whitelist) {
V v = m.get(k);
if (v != null) {
map.put(k, v);
}
}
} else {
map.putAll(m);
}
}
@Override
public V remove(Object key) {
return isMutable(key) ? map.remove(key) : null;
}
@Override
public int size() {
return map.size();
}
@Override
public Collection values() {
return map.values();
}
/**
* Freezes the map to discard write operations.
*
* @return this map
*/
public ClickHouseFreezableMap freeze() {
freezed.compareAndSet(false, true);
return this;
}
/**
* Unfreezes the map to accept write operations.
*
* @return this map
*/
public ClickHouseFreezableMap unfreeze() {
freezed.compareAndSet(true, false);
return this;
}
/**
* Checks whether the map is freezed or not.
*
* @return true if the map is freezed; false otherwise
*/
public boolean isFreezed() {
return freezed.get();
}
/**
* Checks whether the given key is whitelisted, meaning corresponding entry can
* be changed even the map is freezed.
*
* @param key non-null key
* @return true if the key is whitelisted; false otherwise
*/
public boolean isWhiteListed(K key) {
return key != null && whitelist.contains(key);
}
}