Merge branch 'cassandra-4.1' into trunk

This commit is contained in:
Ekaterina Dimitrova 2022-05-20 14:33:36 -04:00
commit c0b175595d
71 changed files with 2270 additions and 1844 deletions

View File

@ -3,6 +3,7 @@
* Add guardrail for ALTER TABLE ADD / DROP / REMOVE column operations (CASSANDRA-17495)
* Rename DisableFlag class to EnableFlag on guardrails (CASSANDRA-17544)
Merged from 4.1:
* Handle config parameters upper bound on startup; Fix auto_snapshot_ttl and paxos_purge_grace_period min unit validations (CASSANDRA-17571)
* Fix leak of non-standard Java types in our Exceptions as clients using JMX are unable to handle them.
Remove useless validation that leads to unnecessary additional read of cassandra.yaml on startup (CASSANDRA-17638)
* Fix repair_request_timeout_in_ms and remove paxos_auto_repair_threshold_mb (CASSANDRA-17557)

View File

@ -183,6 +183,9 @@ New features
Upgrading
---------
- Parameters of type data storage, duration and data rate cannot be set to Long.MAX_VALUE (former parameters of long type)
and Integer.MAX_VALUE (former parameters of int type). Those numbers are used during conversion between units to prevent
an overflow from happening. (CASSANDRA-17571)
- We added new JMX methods `setStreamThroughputMbitPerSec`, `getStreamThroughputMbitPerSec`, `setInterDCStreamThroughputMbitPerSec`,
`getInterDCStreamThroughputMbitPerSec` to the JMX MBean `org.apache.cassandra.db:type=StorageService`. They replace the now
deprecated methods `setStreamThroughputMbPerSec`, `getStreamThroughputMbPerSec`, `setInterDCStreamThroughputMbPerSec`, and

View File

@ -61,6 +61,7 @@ hinted_handoff_enabled: true
# this defines the maximum amount of time a dead host will have hints
# generated. After it has been dead this long, new hints for it will not be
# created until it has been seen alive and gone down again.
# Min unit: ms
max_hint_window: 3h
# Maximum throttle in KBs per second, per delivery thread. This will be
@ -68,6 +69,7 @@ max_hint_window: 3h
# are two nodes in the cluster, each delivery thread will use the maximum
# rate; if there are three, each will throttle to half of the maximum,
# since we expect two nodes to be delivering hints simultaneously.)
# Min unit: KiB
hinted_handoff_throttle: 1024KiB
# Number of threads with which to deliver hints;
@ -81,9 +83,11 @@ max_hints_delivery_threads: 2
# How often hints should be flushed from the internal buffers to disk.
# Will *not* trigger fsync.
# Min unit: ms
hints_flush_period: 10000ms
# Maximum size for a single hints file, in megabytes.
# Min unit: MiB
max_hints_file_size: 128MiB
# The file size limit to store hints for an unreachable host, in mebibytes.
@ -119,6 +123,7 @@ auto_hints_cleanup_enabled: false
# Maximum throttle in KBs per second, total. This will be
# reduced proportionally to the number of nodes in the cluster.
# Min unit: KiB
batchlog_replay_throttle: 1024KiB
# Authentication backend, implementing IAuthenticator; used to identify users
@ -177,6 +182,7 @@ network_authorizer: AllowAllNetworkAuthorizer
# Will be disabled automatically for AllowAllAuthenticator.
# For a long-running cache using roles_cache_active_update, consider
# setting to something longer such as a daily validation: 86400000
# Min unit: ms
roles_validity: 2000ms
# Refresh interval for roles cache (if enabled).
@ -188,6 +194,7 @@ roles_validity: 2000ms
# using roles_cache_active_update.
# Defaults to the same value as roles_validity.
# For a long-running cache, consider setting this to 60000 (1 hour) etc.
# Min unit: ms
# roles_update_interval: 2000ms
# If true, cache contents are actively updated by a background task at the
@ -201,7 +208,8 @@ roles_validity: 2000ms
# one example). Defaults to 2000, set to 0 to disable.
# Will be disabled automatically for AllowAllAuthorizer.
# For a long-running cache using permissions_cache_active_update, consider
# setting to something longer such as a daily validation: 86400000
# setting to something longer such as a daily validation: 86400000ms
# Min unit: ms
permissions_validity: 2000ms
# Refresh interval for permissions cache (if enabled).
@ -213,6 +221,7 @@ permissions_validity: 2000ms
# using permissions_cache_active_update.
# Defaults to the same value as permissions_validity.
# For a longer-running permissions cache, consider setting to update hourly (60000)
# Min unit: ms
# permissions_update_interval: 2000ms
# If true, cache contents are actively updated by a background task at the
@ -232,6 +241,7 @@ permissions_validity: 2000ms
# Defaults to 2000, set to 0 to disable credentials caching.
# For a long-running cache using credentials_cache_active_update, consider
# setting to something longer such as a daily validation: 86400000
# Min unit: ms
credentials_validity: 2000ms
# Refresh interval for credentials cache (if enabled).
@ -243,6 +253,7 @@ credentials_validity: 2000ms
# using credentials_cache_active_update.
# Defaults to the same value as credentials_validity.
# For a longer-running permissions cache, consider setting to update hourly (60000)
# Min unit: ms
# credentials_update_interval: 2000ms
# If true, cache contents are actively updated by a background task at the
@ -350,6 +361,7 @@ commit_failure_policy: stop
# Constantly re-preparing statements is a performance penalty.
#
# Default value ("auto") is 1/256th of the heap or 10MiB, whichever is greater
# Min unit: MiB
# prepared_statements_cache_size:
# Maximum size of the key cache in memory.
@ -363,7 +375,8 @@ commit_failure_policy: stop
#
# NOTE: if you reduce the size, you may not get you hottest keys loaded on startup.
#
# Default value is empty to make it "auto" (min(5% of Heap (in MB), 100MB)). Set to 0 to disable key cache.
# Default value is empty to make it "auto" (min(5% of Heap (in MiB), 100MiB)). Set to 0 to disable key cache.
# Min unit: MiB
# key_cache_size:
# Duration in seconds after which Cassandra should
@ -375,6 +388,7 @@ commit_failure_policy: stop
# has limited use.
#
# Default is 14400 or 4 hours.
# Min unit: s
key_cache_save_period: 4h
# Number of keys from the key cache to save
@ -399,6 +413,7 @@ key_cache_save_period: 4h
# headroom for OS block level cache. Do never allow your system to swap.
#
# Default value is 0, to disable row caching.
# Min unit: MiB
row_cache_size: 0MiB
# Duration in seconds after which Cassandra should save the row cache.
@ -409,6 +424,7 @@ row_cache_size: 0MiB
# has limited use.
#
# Default is 0 to disable saving the row cache.
# Min unit: s
row_cache_save_period: 0s
# Number of keys from the row cache to save.
@ -426,8 +442,9 @@ row_cache_save_period: 0s
#
# NOTE: if you reduce the size, you may not get you hottest keys loaded on startup.
#
# Default value is empty to make it "auto" (min(2.5% of Heap (in MB), 50MB)). Set to 0 to disable counter cache.
# Default value is empty to make it "auto" (min(2.5% of Heap (in MiB), 50MiB)). Set to 0 to disable counter cache.
# NOTE: if you perform counter deletes and rely on low gcgs, you should disable the counter cache.
# Min unit: MiB
# counter_cache_size:
# Duration in seconds after which Cassandra should
@ -435,6 +452,7 @@ row_cache_save_period: 0s
# specified in this configuration file.
#
# Default is 7200 or 2 hours.
# Min unit: s
counter_cache_save_period: 7200s
# Number of keys from the counter cache to save
@ -448,6 +466,7 @@ counter_cache_save_period: 7200s
# Number of seconds the server will wait for each cache (row, key, etc ...) to load while starting
# the Cassandra process. Setting this to zero is equivalent to disabling all cache loading on startup
# while still having the cache during runtime.
# Min unit: s
# cache_load_timeout: 30s
# commitlog_sync may be either "periodic", "group", or "batch."
@ -463,16 +482,19 @@ counter_cache_save_period: 7200s
# until the commit log has been flushed to disk. The difference is group
# mode will wait up to commitlog_sync_group_window between flushes.
#
# Min unit: ms
# commitlog_sync_group_window: 1000ms
#
# the default option is "periodic" where writes may be acked immediately
# and the CommitLog is simply synced every commitlog_sync_period
# milliseconds.
commitlog_sync: periodic
# Min unit: ms
commitlog_sync_period: 10000ms
# When in periodic commitlog mode, the number of milliseconds to block writes
# while waiting for a slow disk flush to complete.
# Min unit: ms
# periodic_commitlog_sync_lag_block:
# The size of the individual commitlog file segments. A commitlog
@ -491,6 +513,7 @@ commitlog_sync_period: 10000ms
# NOTE: If max_mutation_size is set explicitly then commitlog_segment_size must
# be set to at least twice the size of max_mutation_size
#
# Min unit: MiB
commitlog_segment_size: 32MiB
# Compression to apply to the commit log. If omitted, the commit log
@ -555,6 +578,7 @@ concurrent_materialized_view_writes: 32
# overhead which is roughly 128 bytes per chunk (i.e. 0.2% of the reserved size
# if the default 64k chunk size is used).
# Memory is only allocated when needed.
# Min unit: MiB
# networking_cache_size: 128MiB
# Enable the sstable chunk cache. The chunk cache will store recently accessed
@ -569,6 +593,7 @@ concurrent_materialized_view_writes: 32
# overhead which is roughly 128 bytes per chunk (i.e. 0.2% of the reserved size
# if the default 64k chunk size is used).
# Memory is only allocated when needed.
# Min unit: MiB
# file_cache_size: 512MiB
# Flag indicating whether to allocate on or off heap when the sstable buffer
@ -587,7 +612,9 @@ concurrent_materialized_view_writes: 32
# accepting writes when the limit is exceeded until a flush completes,
# and will trigger a flush based on memtable_cleanup_threshold
# If omitted, Cassandra will set both to 1/4 the size of the heap.
# Min unit: MiB
# memtable_heap_space: 2048MiB
# Min unit: MiB
# memtable_offheap_space: 2048MiB
# memtable_cleanup_threshold is deprecated. The default calculation
@ -625,6 +652,7 @@ memtable_allocation_type: heap_buffers
#
# For more details see https://issues.apache.org/jira/browse/CASSANDRA-14096.
#
# Min unit: MiB
# repair_session_space:
# Total space to use for commit logs on disk.
@ -675,11 +703,13 @@ memtable_allocation_type: heap_buffers
#
# The default value is the min of 4096 MiB and 1/8th of the total space
# of the drive where cdc_raw_directory resides.
# Min unit: MiB
# cdc_total_space: 4096MiB
# When we hit our cdc_raw limit and the CDCCompactor is either running behind
# or experiencing backpressure, we check at the following interval to see if any
# new space for cdc-tracked tables has been made available. Default to 250ms
# Min unit: ms
# cdc_free_space_check_interval: 250ms
# A fixed memory pool size in MB for for SSTable index summaries. If left
@ -688,12 +718,14 @@ memtable_allocation_type: heap_buffers
# shrink their index summaries in order to meet this limit. However, this
# is a best-effort process. In extreme conditions Cassandra may need to use
# more than this amount of memory.
# Min unit: KiB
# index_summary_capacity:
# How frequently index summaries should be resampled. This is done
# periodically to redistribute memory from the fixed-size pool to sstables
# proportional their recent read rates. Setting to -1 will disable this
# process, leaving existing index summaries at their current sampling level.
# Min unit: m
index_summary_resize_interval: 60m
# Whether to, when doing sequential writing, fsync() at intervals in
@ -702,6 +734,7 @@ index_summary_resize_interval: 60m
# impacting read latencies. Almost always a good idea on SSDs; not
# necessarily on platters.
trickle_fsync: false
# Min unit: KiB
trickle_fsync_interval: 10240KiB
# TCP port, for commands and data
@ -776,6 +809,7 @@ native_transport_port: 9042
# The maximum size of allowed frame. Frame (requests) larger than this will
# be rejected as invalid. The default is 16MiB. If you're changing this parameter,
# you may want to adjust max_value_size accordingly. This should be positive and less than 2048.
# Min unit: MiB
# native_transport_max_frame_size: 16MiB
# The maximum number of concurrent client connections.
@ -798,6 +832,7 @@ native_transport_allow_older_protocols: true
# values for heartbeat intervals have to be set on the client side.
#
# Idle connection timeouts are disabled by default.
# Min unit: ms
# native_transport_idle_timeout: 60000ms
# When enabled, limits the number of native transport requests dispatched for processing per second.
@ -851,11 +886,13 @@ rpc_keepalive: true
# /proc/sys/net/ipv4/tcp_wmem
# /proc/sys/net/ipv4/tcp_wmem
# and 'man tcp'
# Min unit: B
# internode_socket_send_buffer_size:
# Uncomment to set socket buffer size for internode communication
# Note that when setting this, the buffer size is limited by net.core.wmem_max
# and when not setting it it is defined by net.ipv4.tcp_wmem
# Min unit: B
# internode_socket_receive_buffer_size:
# Set to true to have Cassandra create a hard link to each sstable
@ -901,6 +938,7 @@ snapshot_links_per_second: 0
# - but, Cassandra will keep the collation index in memory for hot
# rows (as part of the key cache), so a larger granularity means
# you can cache more hot rows
# Min unit: KiB
column_index_size: 64KiB
# Per sstable indexed key cache entries (the collation index in memory
@ -910,6 +948,7 @@ column_index_size: 64KiB
#
# Note that this size refers to the size of the
# serialized index information and not the size of the partition.
# Min unit: KiB
column_index_cache_size: 2KiB
# Number of simultaneous compactions to allow, NOT including
@ -953,6 +992,7 @@ compaction_throughput: 64MiB/s
# are completely written, and used in place of the prior sstables for
# any range that has been written. This helps to smoothly transfer reads
# between the sstables, reducing page cache churn and keeping hot rows hot
# Min unit: MiB
sstable_preemptive_open_interval: 50MiB
# Starting from 4.1 sstables support UUID based generation identifiers. They are disabled by default
@ -1014,43 +1054,53 @@ enable_uuid_sstable_identifiers: false
# How long the coordinator should wait for read operations to complete.
# Lowest acceptable value is 10 ms.
# Min unit: ms
read_request_timeout: 5000ms
# How long the coordinator should wait for seq or index scans to complete.
# Lowest acceptable value is 10 ms.
# Min unit: ms
range_request_timeout: 10000ms
# How long the coordinator should wait for writes to complete.
# Lowest acceptable value is 10 ms.
# Min unit: ms
write_request_timeout: 2000ms
# How long the coordinator should wait for counter writes to complete.
# Lowest acceptable value is 10 ms.
# Min unit: ms
counter_write_request_timeout: 5000ms
# How long a coordinator should continue to retry a CAS operation
# that contends with other proposals for the same row.
# Lowest acceptable value is 10 ms.
# Min unit: ms
cas_contention_timeout: 1000ms
# How long the coordinator should wait for truncates to complete
# (This can be much longer, because unless auto_snapshot is disabled
# we need to flush first so we can snapshot before removing the data.)
# Lowest acceptable value is 10 ms.
# Min unit: ms
truncate_request_timeout: 60000ms
# The default timeout for other, miscellaneous operations.
# Lowest acceptable value is 10 ms.
# Min unit: ms
request_timeout: 10000ms
# Defensive settings for protecting Cassandra from true network partitions.
# See (CASSANDRA-14358) for details.
#
# The amount of time to wait for internode tcp connections to establish.
# Min unit: ms
# internode_tcp_connect_timeout: 2000ms
#
# The amount of time unacknowledged data is allowed on a connection before we throw out the connection
# Note this is only supported on Linux + epoll, and it appears to behave oddly above a setting of 30000
# (it takes much longer than 30s) as of Linux 4.12. If you want something that high set this to 0
# which picks up the OS default and configure the net.ipv4.tcp_retries2 sysctl to be ~8.
# Min unit: ms
# internode_tcp_user_timeout: 30000ms
# The amount of time unacknowledged data is allowed on a streaming connection.
# The default is 5 minutes. Increase it or set it to 0 in order to increase the timeout.
# Min unit: ms
# internode_streaming_tcp_user_timeout: 300000ms
# Global, per-endpoint and per-connection limits imposed on messages queued for delivery to other nodes
@ -1068,6 +1118,7 @@ request_timeout: 10000ms
# The global limit is imposed on all messages exceeding the per-link limit, simultaneously with the per-endpoint limit,
# on all links to or from any node in the cluster.
#
# Min unit: B
# internode_application_send_queue_capacity: 4MiB
# internode_application_send_queue_reserve_endpoint_capacity: 128MiB
# internode_application_send_queue_reserve_global_capacity: 512MiB
@ -1079,6 +1130,7 @@ request_timeout: 10000ms
# How long before a node logs slow queries. Select queries that take longer than
# this timeout to execute, will generate an aggregated log message, so that slow queries
# can be identified. Set this value to zero to disable slow query logging.
# Min unit: ms
slow_query_log_timeout: 500ms
# Enable operation timeout information exchange between nodes to accurately
@ -1097,6 +1149,7 @@ slow_query_log_timeout: 500ms
# 2 keep-alive cycles the stream session times out and fail
# Default value is 300s (5 minutes), which means stalled stream
# times out in 10 minutes by default
# Min unit: s
# streaming_keep_alive_period: 300s
# Limit number of connections per host for streaming
@ -1115,9 +1168,11 @@ slow_query_log_timeout: 500ms
# The interval at which keys in the cache for denylisting will "expire" and async refresh from the backing DB.
# Note: this serves only as a fail-safe, as the usage pattern is expected to be "mutate state, refresh cache" on any
# changes to the underlying denylist entries. See documentation for details.
# Min unit: s
# denylist_refresh: 600s
# In the event of errors on attempting to load the denylist cache, retry on this interval.
# Min unit: s
# denylist_initial_load_retry: 5s
# We cap the number of denylisted keys allowed per table to keep things from growing unbounded. Nodes will warn above
@ -1206,9 +1261,11 @@ endpoint_snitch: SimpleSnitch
# controls how often to perform the more expensive part of host score
# calculation
# Min unit: ms
dynamic_snitch_update_interval: 100ms
# controls how often to reset all host scores, allowing a bad host to
# possibly recover
# Min unit: ms
dynamic_snitch_reset_interval: 600000ms
# if set greater than zero, this will allow
# 'pinning' of replicas to hosts in order to increase cache capacity.
@ -1334,7 +1391,9 @@ internode_compression: dc
inter_dc_tcp_nodelay: false
# TTL for different trace types used during logging of the repair process.
# Min unit: s
trace_type_query_ttl: 1d
# Min unit: s
trace_type_repair_ttl: 7d
# If unset, all GC Pauses greater than gc_log_threshold will log at
@ -1415,9 +1474,11 @@ replica_filtering_protection:
# Log WARN on any multiple-partition batch size exceeding this value. 5KiB per batch by default.
# Caution should be taken on increasing the size of this threshold as it can lead to node instability.
# Min unit: KiB
batch_size_warn_threshold: 5KiB
# Fail any multiple-partition batch exceeding this value. 50KiB (10x warn threshold) by default.
# Min unit: KiB
batch_size_fail_threshold: 50KiB
# Log WARN on any batches not of type LOGGED than span across more partitions than this limit
@ -1431,16 +1492,19 @@ compaction_tombstone_warning_threshold: 100000
# GC Pauses greater than 200 ms will be logged at INFO level
# This threshold can be adjusted to minimize logging if necessary
# Min unit: ms
# gc_log_threshold: 200ms
# GC Pauses greater than gc_warn_threshold will be logged at WARN level
# Adjust the threshold based on your application throughput requirement. Setting to 0
# will deactivate the feature.
# Min unit: ms
# gc_warn_threshold: 1000ms
# Maximum size of any value in SSTables. Safety measure to detect SSTable corruption
# early. Any value size larger than this threshold will result into marking an SSTable
# as corrupted. This should be positive and less than 2GiB.
# Min unit: MiB
# max_value_size: 256MiB
# ** Impact on keyspace creation **
@ -1676,7 +1740,9 @@ drop_compact_storage_enabled: false
# prevent read-before-write. The guardrail is also checked at sstable write time to detect large non-frozen collections,
# although in that case exceeding the fail threshold will only log an error message, without interrupting the operation.
# The two thresholds default to null to disable.
# Min unit: B
# collection_size_warn_threshold:
# Min unit: B
# collection_size_fail_threshold:
#
# Guardrail to warn or fail when encountering more elements in collection than threshold.
@ -1717,6 +1783,7 @@ drop_compact_storage_enabled: false
# be useful when we have a large disk and we only want to use a part of it for Cassandra's data directories.
# Valid values are in [1, max available disk size of all data directories].
# Defaults to null to disable and use the physically available disk size of data directories during calculations.
# Min unit: B
# data_disk_usage_max_disk_size:
#
# Guardrail to warn or fail when the minimum replication factor is lesser than threshold.

View File

@ -152,14 +152,22 @@ If the parameter is of type duration, data rate or data storage, its value shoul
- Please follow the new format `noun_verb` when adding new configuration parameters.
- Please consider adding any new parameters with the lowest supported by Cassandra unit.
- Please consider adding any new parameters with the lowest supported by Cassandra unit when possible. Our new types also
support long and integer upper bound, depending on your needs. All options for configuration parameters' types are nested
classes in our three main abstract classes - `DurationSpec`, `DataStorageSpec`, `DataRateSpec`.
- If for some reason you consider the smallest unit shouldnt be the one that is supported as such in Cassandra, please,
use the extended classes `SmallestDuration*`, `SmallestDataStorage*`.
- If for some reason you consider the smallest unit for a new parameter shouldnt be the one that is supported as such in
Cassandra, you can use the rest of the nested classes in `DurationSpec`, `DataStorageSpec`. The smallest allowed unit is
the one we use internally for the property, so we don't have to do conversions to bigger units which will lead to precision
problems. This is a problem only with `DurationSpec` and `DataStorageSpec`. `DataRateSpec` is handled internally in double.
- New parameters should be added as non-negative numbers. For parameters where you would have set -1 to disable in the past, you might
want to consider a separate flag parameter or null value. In case you use the null value, please, ensure that any default value
introduced in the DatabaDescriptor to handle it is also duplicated in any related setters.
introduced in the DatabaseDescriptor to handle it is also duplicated in any related setters.
- Parameters of type data storage, duration and data rate cannot be set to Long.MAX_VALUE (former parameters of long type)
and Integer.MAX_VALUE (former parameters of int type). That numbers are used during conversion between units to prevent
an overflow from happening.
- Any time you add @Replaces with a name change, we need to add an entry in this https://github.com/riptano/ccm/blob/808b6ca13526785b0fddfe1ead2383c060c4b8b6/ccmlib/common.py#L62[Python dictionary in CCM] to support the same backward compatibility as SnakeYAML.
@ -194,3 +202,6 @@ hinted_handoff_enabled: false
....
https://issues.apache.org/jira/browse/CASSANDRA-17379[CASSANDRA-17379] was opened to improve the user experience and deprecate the overloading.
By default, we refuse starting Cassandra with a config containing both old and new config keys for the same parameter. Start
Cassandra with `-Dcassandra.allow_new_old_config_keys=true` to override. For historical reasons duplicate config keys
in `cassandra.yaml` are allowed by default, start Cassandra with `-Dcassandra.allow_duplicate_config_keys=false` to disallow this.

View File

@ -57,7 +57,7 @@ public final class AuthConfig
// is in use and non-default values are detected
if (!(authenticator instanceof PasswordAuthenticator)
&& (conf.credentials_update_interval != null
|| conf.credentials_validity.toMillisecondsAsInt() != 2000
|| conf.credentials_validity.toMilliseconds() != 2000
|| conf.credentials_cache_max_entries != 1000))
{
logger.info("Configuration options credentials_update_interval, credentials_validity and " +

View File

@ -74,22 +74,22 @@ public class Config
public String role_manager;
public String network_authorizer;
@Replaces(oldName = "permissions_validity_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public volatile SmallestDurationMilliseconds permissions_validity = new SmallestDurationMilliseconds("2s");
public volatile DurationSpec.IntMillisecondsBound permissions_validity = new DurationSpec.IntMillisecondsBound("2s");
public volatile int permissions_cache_max_entries = 1000;
@Replaces(oldName = "permissions_update_interval_in_ms", converter = Converters.MILLIS_CUSTOM_DURATION, deprecated = true)
public volatile SmallestDurationMilliseconds permissions_update_interval = null;
public volatile DurationSpec.IntMillisecondsBound permissions_update_interval = null;
public volatile boolean permissions_cache_active_update = false;
@Replaces(oldName = "roles_validity_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public volatile SmallestDurationMilliseconds roles_validity = new SmallestDurationMilliseconds("2s");
public volatile DurationSpec.IntMillisecondsBound roles_validity = new DurationSpec.IntMillisecondsBound("2s");
public volatile int roles_cache_max_entries = 1000;
@Replaces(oldName = "roles_update_interval_in_ms", converter = Converters.MILLIS_CUSTOM_DURATION, deprecated = true)
public volatile SmallestDurationMilliseconds roles_update_interval = null;
public volatile DurationSpec.IntMillisecondsBound roles_update_interval = null;
public volatile boolean roles_cache_active_update = false;
@Replaces(oldName = "credentials_validity_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public volatile SmallestDurationMilliseconds credentials_validity = new SmallestDurationMilliseconds("2s");
public volatile DurationSpec.IntMillisecondsBound credentials_validity = new DurationSpec.IntMillisecondsBound("2s");
public volatile int credentials_cache_max_entries = 1000;
@Replaces(oldName = "credentials_update_interval_in_ms", converter = Converters.MILLIS_CUSTOM_DURATION, deprecated = true)
public volatile SmallestDurationMilliseconds credentials_update_interval = null;
public volatile DurationSpec.IntMillisecondsBound credentials_update_interval = null;
public volatile boolean credentials_cache_active_update = false;
/* Hashing strategy Random or OPHF */
@ -99,7 +99,7 @@ public class Config
public volatile boolean hinted_handoff_enabled = true;
public Set<String> hinted_handoff_disabled_datacenters = Sets.newConcurrentHashSet();
@Replaces(oldName = "max_hint_window_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public volatile SmallestDurationMilliseconds max_hint_window = new SmallestDurationMilliseconds("3h");
public volatile DurationSpec.IntMillisecondsBound max_hint_window = new DurationSpec.IntMillisecondsBound("3h");
public String hints_directory;
public boolean hint_window_persistent_enabled = true;
@ -122,40 +122,40 @@ public class Config
public Integer allocate_tokens_for_local_replication_factor = null;
@Replaces(oldName = "native_transport_idle_timeout_in_ms", converter = Converters.MILLIS_DURATION_LONG, deprecated = true)
public SmallestDurationMilliseconds native_transport_idle_timeout = new SmallestDurationMilliseconds("0ms");
public DurationSpec.LongMillisecondsBound native_transport_idle_timeout = new DurationSpec.LongMillisecondsBound("0ms");
@Replaces(oldName = "request_timeout_in_ms", converter = Converters.MILLIS_DURATION_LONG, deprecated = true)
public volatile SmallestDurationMilliseconds request_timeout = new SmallestDurationMilliseconds("10000ms");
public volatile DurationSpec.LongMillisecondsBound request_timeout = new DurationSpec.LongMillisecondsBound("10000ms");
@Replaces(oldName = "read_request_timeout_in_ms", converter = Converters.MILLIS_DURATION_LONG, deprecated = true)
public volatile SmallestDurationMilliseconds read_request_timeout = new SmallestDurationMilliseconds("5000ms");
public volatile DurationSpec.LongMillisecondsBound read_request_timeout = new DurationSpec.LongMillisecondsBound("5000ms");
@Replaces(oldName = "range_request_timeout_in_ms", converter = Converters.MILLIS_DURATION_LONG, deprecated = true)
public volatile SmallestDurationMilliseconds range_request_timeout = new SmallestDurationMilliseconds("10000ms");
public volatile DurationSpec.LongMillisecondsBound range_request_timeout = new DurationSpec.LongMillisecondsBound("10000ms");
@Replaces(oldName = "write_request_timeout_in_ms", converter = Converters.MILLIS_DURATION_LONG, deprecated = true)
public volatile SmallestDurationMilliseconds write_request_timeout = new SmallestDurationMilliseconds("2000ms");
public volatile DurationSpec.LongMillisecondsBound write_request_timeout = new DurationSpec.LongMillisecondsBound("2000ms");
@Replaces(oldName = "counter_write_request_timeout_in_ms", converter = Converters.MILLIS_DURATION_LONG, deprecated = true)
public volatile SmallestDurationMilliseconds counter_write_request_timeout = new SmallestDurationMilliseconds("5000ms");
public volatile DurationSpec.LongMillisecondsBound counter_write_request_timeout = new DurationSpec.LongMillisecondsBound("5000ms");
@Replaces(oldName = "cas_contention_timeout_in_ms", converter = Converters.MILLIS_DURATION_LONG, deprecated = true)
public volatile SmallestDurationMilliseconds cas_contention_timeout = new SmallestDurationMilliseconds("1800ms");
public volatile DurationSpec.LongMillisecondsBound cas_contention_timeout = new DurationSpec.LongMillisecondsBound("1800ms");
@Replaces(oldName = "truncate_request_timeout_in_ms", converter = Converters.MILLIS_DURATION_LONG, deprecated = true)
public volatile SmallestDurationMilliseconds truncate_request_timeout = new SmallestDurationMilliseconds("60000ms");
public volatile DurationSpec.LongMillisecondsBound truncate_request_timeout = new DurationSpec.LongMillisecondsBound("60000ms");
public volatile SmallestDurationMilliseconds repair_request_timeout = new SmallestDurationMilliseconds("120000ms");
public volatile DurationSpec.LongMillisecondsBound repair_request_timeout = new DurationSpec.LongMillisecondsBound("120000ms");
public Integer streaming_connections_per_host = 1;
@Replaces(oldName = "streaming_keep_alive_period_in_secs", converter = Converters.SECONDS_DURATION, deprecated = true)
public SmallestDurationSeconds streaming_keep_alive_period = new SmallestDurationSeconds("300s");
public DurationSpec.IntSecondsBound streaming_keep_alive_period = new DurationSpec.IntSecondsBound("300s");
@Replaces(oldName = "cross_node_timeout", converter = Converters.IDENTITY, deprecated = true)
public boolean internode_timeout = true;
@Replaces(oldName = "slow_query_log_timeout_in_ms", converter = Converters.MILLIS_DURATION_LONG, deprecated = true)
public volatile SmallestDurationMilliseconds slow_query_log_timeout = new SmallestDurationMilliseconds("500ms");
public volatile DurationSpec.LongMillisecondsBound slow_query_log_timeout = new DurationSpec.LongMillisecondsBound("500ms");
public volatile double phi_convict_threshold = 8.0;
@ -170,9 +170,9 @@ public class Config
public int memtable_flush_writers = 0;
@Replaces(oldName = "memtable_heap_space_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public SmallestDataStorageMebibytes memtable_heap_space;
public DataStorageSpec.IntMebibytesBound memtable_heap_space;
@Replaces(oldName = "memtable_offheap_space_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public SmallestDataStorageMebibytes memtable_offheap_space;
public DataStorageSpec.IntMebibytesBound memtable_offheap_space;
public Float memtable_cleanup_threshold = null;
public static class MemtableOptions
@ -190,7 +190,7 @@ public class Config
@Deprecated
public volatile Integer repair_session_max_tree_depth = null;
@Replaces(oldName = "repair_session_space_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public volatile SmallestDataStorageMebibytes repair_session_space = null;
public volatile DataStorageSpec.IntMebibytesBound repair_session_space = null;
public volatile boolean use_offheap_merkle_trees = true;
@ -219,51 +219,51 @@ public class Config
public boolean rpc_keepalive = true;
@Replaces(oldName = "internode_max_message_size_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated=true)
public DataStorageSpec internode_max_message_size;
public DataStorageSpec.IntBytesBound internode_max_message_size;
@Replaces(oldName = "internode_socket_send_buffer_size_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
@Replaces(oldName = "internode_send_buff_size_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
public DataStorageSpec internode_socket_send_buffer_size = new DataStorageSpec("0B");
public DataStorageSpec.IntBytesBound internode_socket_send_buffer_size = new DataStorageSpec.IntBytesBound("0B");
@Replaces(oldName = "internode_socket_receive_buffer_size_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
@Replaces(oldName = "internode_recv_buff_size_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
public DataStorageSpec internode_socket_receive_buffer_size = new DataStorageSpec("0B");
public DataStorageSpec.IntBytesBound internode_socket_receive_buffer_size = new DataStorageSpec.IntBytesBound("0B");
// TODO: derive defaults from system memory settings?
@Replaces(oldName = "internode_application_send_queue_capacity_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
public DataStorageSpec internode_application_send_queue_capacity = new DataStorageSpec("4MiB");
public DataStorageSpec.IntBytesBound internode_application_send_queue_capacity = new DataStorageSpec.IntBytesBound("4MiB");
@Replaces(oldName = "internode_application_send_queue_reserve_endpoint_capacity_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
public DataStorageSpec internode_application_send_queue_reserve_endpoint_capacity = new DataStorageSpec("128MiB");
public DataStorageSpec.IntBytesBound internode_application_send_queue_reserve_endpoint_capacity = new DataStorageSpec.IntBytesBound("128MiB");
@Replaces(oldName = "internode_application_send_queue_reserve_global_capacity_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
public DataStorageSpec internode_application_send_queue_reserve_global_capacity = new DataStorageSpec("512MiB");
public DataStorageSpec.IntBytesBound internode_application_send_queue_reserve_global_capacity = new DataStorageSpec.IntBytesBound("512MiB");
@Replaces(oldName = "internode_application_receive_queue_capacity_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
public DataStorageSpec internode_application_receive_queue_capacity = new DataStorageSpec("4MiB");
public DataStorageSpec.IntBytesBound internode_application_receive_queue_capacity = new DataStorageSpec.IntBytesBound("4MiB");
@Replaces(oldName = "internode_application_receive_queue_reserve_endpoint_capacity_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
public DataStorageSpec internode_application_receive_queue_reserve_endpoint_capacity = new DataStorageSpec("128MiB");
public DataStorageSpec.IntBytesBound internode_application_receive_queue_reserve_endpoint_capacity = new DataStorageSpec.IntBytesBound("128MiB");
@Replaces(oldName = "internode_application_receive_queue_reserve_global_capacity_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
public DataStorageSpec internode_application_receive_queue_reserve_global_capacity = new DataStorageSpec("512MiB");
public DataStorageSpec.IntBytesBound internode_application_receive_queue_reserve_global_capacity = new DataStorageSpec.IntBytesBound("512MiB");
// Defensive settings for protecting Cassandra from true network partitions. See (CASSANDRA-14358) for details.
// The amount of time to wait for internode tcp connections to establish.
@Replaces(oldName = "internode_tcp_connect_timeout_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public volatile SmallestDurationMilliseconds internode_tcp_connect_timeout = new SmallestDurationMilliseconds("2s");
public volatile DurationSpec.IntMillisecondsBound internode_tcp_connect_timeout = new DurationSpec.IntMillisecondsBound("2s");
// The amount of time unacknowledged data is allowed on a connection before we throw out the connection
// Note this is only supported on Linux + epoll, and it appears to behave oddly above a setting of 30000
// (it takes much longer than 30s) as of Linux 4.12. If you want something that high set this to 0
// (which picks up the OS default) and configure the net.ipv4.tcp_retries2 sysctl to be ~8.
@Replaces(oldName = "internode_tcp_user_timeout_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public volatile SmallestDurationMilliseconds internode_tcp_user_timeout = new SmallestDurationMilliseconds("30s");
public volatile DurationSpec.IntMillisecondsBound internode_tcp_user_timeout = new DurationSpec.IntMillisecondsBound("30s");
// Similar to internode_tcp_user_timeout but used specifically for streaming connection.
// The default is 5 minutes. Increase it or set it to 0 in order to increase the timeout.
@Replaces(oldName = "internode_streaming_tcp_user_timeout_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public volatile SmallestDurationMilliseconds internode_streaming_tcp_user_timeout = new SmallestDurationMilliseconds("300s"); // 5 minutes
public volatile DurationSpec.IntMillisecondsBound internode_streaming_tcp_user_timeout = new DurationSpec.IntMillisecondsBound("300s"); // 5 minutes
public boolean start_native_transport = true;
public int native_transport_port = 9042;
public Integer native_transport_port_ssl = null;
public int native_transport_max_threads = 128;
@Replaces(oldName = "native_transport_max_frame_size_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public SmallestDataStorageMebibytes native_transport_max_frame_size = new SmallestDataStorageMebibytes("16MiB");
public DataStorageSpec.IntMebibytesBound native_transport_max_frame_size = new DataStorageSpec.IntMebibytesBound("16MiB");
public volatile long native_transport_max_concurrent_connections = -1L;
public volatile long native_transport_max_concurrent_connections_per_ip = -1L;
public boolean native_transport_flush_in_batches_legacy = false;
@ -271,13 +271,13 @@ public class Config
// Below 2 parameters were fixed in 4.0 + to get default value when ==-1 (old name and value format) or ==null(new name and value format),
// not <=0 as it is in previous versions. Throwing config exceptions on < -1
@Replaces(oldName = "native_transport_max_concurrent_requests_in_bytes_per_ip", converter = Converters.BYTES_CUSTOM_DATASTORAGE, deprecated = true)
public volatile DataStorageSpec native_transport_max_request_data_in_flight_per_ip = null;
public volatile DataStorageSpec.LongBytesBound native_transport_max_request_data_in_flight_per_ip = null;
@Replaces(oldName = "native_transport_max_concurrent_requests_in_bytes", converter = Converters.BYTES_CUSTOM_DATASTORAGE, deprecated = true)
public volatile DataStorageSpec native_transport_max_request_data_in_flight = null;
public volatile DataStorageSpec.LongBytesBound native_transport_max_request_data_in_flight = null;
public volatile boolean native_transport_rate_limiting_enabled = false;
public volatile int native_transport_max_requests_per_second = 1000000;
@Replaces(oldName = "native_transport_receive_queue_capacity_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
public DataStorageSpec native_transport_receive_queue_capacity = new DataStorageSpec("1MiB");
public DataStorageSpec.IntBytesBound native_transport_receive_queue_capacity = new DataStorageSpec.IntBytesBound("1MiB");
@Deprecated
public Integer native_transport_max_negotiable_protocol_version = null;
@ -288,7 +288,7 @@ public class Config
* See AbstractType for how it is used.
*/
@Replaces(oldName = "max_value_size_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public SmallestDataStorageMebibytes max_value_size = new SmallestDataStorageMebibytes("256MiB");
public DataStorageSpec.IntMebibytesBound max_value_size = new DataStorageSpec.IntMebibytesBound("256MiB");
public boolean snapshot_before_compaction = false;
public boolean auto_snapshot = true;
@ -304,22 +304,22 @@ public class Config
/* if the size of columns or super-columns are more than this, indexing will kick in */
@Replaces(oldName = "column_index_size_in_kb", converter = Converters.KIBIBYTES_DATASTORAGE, deprecated = true)
public volatile SmallestDataStorageKibibytes column_index_size = new SmallestDataStorageKibibytes("64KiB");
public volatile DataStorageSpec.IntKibibytesBound column_index_size = new DataStorageSpec.IntKibibytesBound("64KiB");
@Replaces(oldName = "column_index_cache_size_in_kb", converter = Converters.KIBIBYTES_DATASTORAGE, deprecated = true)
public volatile SmallestDataStorageKibibytes column_index_cache_size = new SmallestDataStorageKibibytes("2KiB");
public volatile DataStorageSpec.IntKibibytesBound column_index_cache_size = new DataStorageSpec.IntKibibytesBound("2KiB");
@Replaces(oldName = "batch_size_warn_threshold_in_kb", converter = Converters.KIBIBYTES_DATASTORAGE, deprecated = true)
public volatile SmallestDataStorageKibibytes batch_size_warn_threshold = new SmallestDataStorageKibibytes("5KiB");
public volatile DataStorageSpec.IntKibibytesBound batch_size_warn_threshold = new DataStorageSpec.IntKibibytesBound("5KiB");
@Replaces(oldName = "batch_size_fail_threshold_in_kb", converter = Converters.KIBIBYTES_DATASTORAGE, deprecated = true)
public volatile SmallestDataStorageKibibytes batch_size_fail_threshold = new SmallestDataStorageKibibytes("50KiB");
public volatile DataStorageSpec.IntKibibytesBound batch_size_fail_threshold = new DataStorageSpec.IntKibibytesBound("50KiB");
public Integer unlogged_batch_across_partitions_warn_threshold = 10;
public volatile Integer concurrent_compactors;
@Replaces(oldName = "compaction_throughput_mb_per_sec", converter = Converters.MEBIBYTES_PER_SECOND_DATA_RATE, deprecated = true)
public volatile DataRateSpec compaction_throughput = new DataRateSpec("16MiB/s");
public volatile DataRateSpec.IntMebibytesPerSecondBound compaction_throughput = new DataRateSpec.IntMebibytesPerSecondBound("16MiB/s");
@Replaces(oldName = "compaction_large_partition_warning_threshold_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public volatile SmallestDataStorageMebibytes compaction_large_partition_warning_threshold = new SmallestDataStorageMebibytes("100MiB");
public volatile DataStorageSpec.IntMebibytesBound compaction_large_partition_warning_threshold = new DataStorageSpec.IntMebibytesBound("100MiB");
@Replaces(oldName = "min_free_space_per_drive_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public SmallestDataStorageMebibytes min_free_space_per_drive = new SmallestDataStorageMebibytes("50MiB");
public DataStorageSpec.IntMebibytesBound min_free_space_per_drive = new DataStorageSpec.IntMebibytesBound("50MiB");
public volatile Integer compaction_tombstone_warning_threshold = 100000;
public volatile int concurrent_materialized_view_builders = 1;
@ -332,12 +332,12 @@ public class Config
public int max_streaming_retries = 3;
@Replaces(oldName = "stream_throughput_outbound_megabits_per_sec", converter = Converters.MEGABITS_TO_MEBIBYTES_PER_SECOND_DATA_RATE, deprecated = true)
public volatile DataRateSpec stream_throughput_outbound = new DataRateSpec("24MiB/s");
public volatile DataRateSpec.IntMebibytesPerSecondBound stream_throughput_outbound = new DataRateSpec.IntMebibytesPerSecondBound("24MiB/s");
@Replaces(oldName = "inter_dc_stream_throughput_outbound_megabits_per_sec", converter = Converters.MEGABITS_TO_MEBIBYTES_PER_SECOND_DATA_RATE, deprecated = true)
public volatile DataRateSpec inter_dc_stream_throughput_outbound = new DataRateSpec("24MiB/s");
public volatile DataRateSpec.IntMebibytesPerSecondBound inter_dc_stream_throughput_outbound = new DataRateSpec.IntMebibytesPerSecondBound("24MiB/s");
public volatile DataRateSpec entire_sstable_stream_throughput_outbound = new DataRateSpec("24MiB/s");
public volatile DataRateSpec entire_sstable_inter_dc_stream_throughput_outbound = new DataRateSpec("24MiB/s");
public volatile DataRateSpec.IntMebibytesPerSecondBound entire_sstable_stream_throughput_outbound = new DataRateSpec.IntMebibytesPerSecondBound("24MiB/s");
public volatile DataRateSpec.IntMebibytesPerSecondBound entire_sstable_inter_dc_stream_throughput_outbound = new DataRateSpec.IntMebibytesPerSecondBound("24MiB/s");
public String[] data_file_directories = new String[0];
@ -352,7 +352,7 @@ public class Config
// Commit Log
public String commitlog_directory;
@Replaces(oldName = "commitlog_total_space_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public SmallestDataStorageMebibytes commitlog_total_space;
public DataStorageSpec.IntMebibytesBound commitlog_total_space;
public CommitLogSync commitlog_sync;
/**
@ -360,20 +360,20 @@ public class Config
*/
public double commitlog_sync_batch_window_in_ms = Double.NaN;
@Replaces(oldName = "commitlog_sync_group_window_in_ms", converter = Converters.MILLIS_DURATION_DOUBLE, deprecated = true)
public SmallestDurationMilliseconds commitlog_sync_group_window = new SmallestDurationMilliseconds("0ms");
public DurationSpec.IntMillisecondsBound commitlog_sync_group_window = new DurationSpec.IntMillisecondsBound("0ms");
@Replaces(oldName = "commitlog_sync_period_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public SmallestDurationMilliseconds commitlog_sync_period = new SmallestDurationMilliseconds("0ms");
public DurationSpec.IntMillisecondsBound commitlog_sync_period = new DurationSpec.IntMillisecondsBound("0ms");
@Replaces(oldName = "commitlog_segment_size_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public SmallestDataStorageMebibytes commitlog_segment_size = new SmallestDataStorageMebibytes("32MiB");
public DataStorageSpec.IntMebibytesBound commitlog_segment_size = new DataStorageSpec.IntMebibytesBound("32MiB");
public ParameterizedClass commitlog_compression;
public FlushCompression flush_compression = FlushCompression.fast;
public int commitlog_max_compression_buffers_in_pool = 3;
@Replaces(oldName = "periodic_commitlog_sync_lag_block_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public SmallestDurationMilliseconds periodic_commitlog_sync_lag_block;
public DurationSpec.IntMillisecondsBound periodic_commitlog_sync_lag_block;
public TransparentDataEncryptionOptions transparent_data_encryption_options = new TransparentDataEncryptionOptions();
@Replaces(oldName = "max_mutation_size_in_kb", converter = Converters.KIBIBYTES_DATASTORAGE, deprecated = true)
public SmallestDataStorageKibibytes max_mutation_size;
public DataStorageSpec.IntKibibytesBound max_mutation_size;
// Change-data-capture logs
public boolean cdc_enabled = false;
@ -382,9 +382,9 @@ public class Config
public volatile boolean cdc_block_writes = true;
public String cdc_raw_directory;
@Replaces(oldName = "cdc_total_space_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public SmallestDataStorageMebibytes cdc_total_space = new SmallestDataStorageMebibytes("0MiB");
public DataStorageSpec.IntMebibytesBound cdc_total_space = new DataStorageSpec.IntMebibytesBound("0MiB");
@Replaces(oldName = "cdc_free_space_check_interval_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public SmallestDurationMilliseconds cdc_free_space_check_interval = new SmallestDurationMilliseconds("250ms");
public DurationSpec.IntMillisecondsBound cdc_free_space_check_interval = new DurationSpec.IntMillisecondsBound("250ms");
@Deprecated
public int commitlog_periodic_queue_size = -1;
@ -392,9 +392,9 @@ public class Config
public String endpoint_snitch;
public boolean dynamic_snitch = true;
@Replaces(oldName = "dynamic_snitch_update_interval_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public SmallestDurationMilliseconds dynamic_snitch_update_interval = new SmallestDurationMilliseconds("100ms");
public DurationSpec.IntMillisecondsBound dynamic_snitch_update_interval = new DurationSpec.IntMillisecondsBound("100ms");
@Replaces(oldName = "dynamic_snitch_reset_interval_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public SmallestDurationMilliseconds dynamic_snitch_reset_interval = new SmallestDurationMilliseconds("10m");
public DurationSpec.IntMillisecondsBound dynamic_snitch_reset_interval = new DurationSpec.IntMillisecondsBound("10m");
public double dynamic_snitch_badness_threshold = 1.0;
public String failure_detector = "FailureDetector";
@ -405,15 +405,15 @@ public class Config
public InternodeCompression internode_compression = InternodeCompression.none;
@Replaces(oldName = "hinted_handoff_throttle_in_kb", converter = Converters.KIBIBYTES_DATASTORAGE, deprecated = true)
public SmallestDataStorageKibibytes hinted_handoff_throttle = new SmallestDataStorageKibibytes("1024KiB");
public DataStorageSpec.IntKibibytesBound hinted_handoff_throttle = new DataStorageSpec.IntKibibytesBound("1024KiB");
@Replaces(oldName = "batchlog_replay_throttle_in_kb", converter = Converters.KIBIBYTES_DATASTORAGE, deprecated = true)
public SmallestDataStorageKibibytes batchlog_replay_throttle = new SmallestDataStorageKibibytes("1024KiB");
public DataStorageSpec.IntKibibytesBound batchlog_replay_throttle = new DataStorageSpec.IntKibibytesBound("1024KiB");
public int max_hints_delivery_threads = 2;
@Replaces(oldName = "hints_flush_period_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public SmallestDurationMilliseconds hints_flush_period = new SmallestDurationMilliseconds("10s");
public DurationSpec.IntMillisecondsBound hints_flush_period = new DurationSpec.IntMillisecondsBound("10s");
@Replaces(oldName = "max_hints_file_size_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public SmallestDataStorageMebibytes max_hints_file_size = new SmallestDataStorageMebibytes("128MiB");
public volatile DataStorageSpec max_hints_size_per_host = new DataStorageSpec("0B"); // 0 means disabled
public DataStorageSpec.IntMebibytesBound max_hints_file_size = new DataStorageSpec.IntMebibytesBound("128MiB");
public volatile DataStorageSpec.LongBytesBound max_hints_size_per_host = new DataStorageSpec.LongBytesBound("0B"); // 0 means disabled
public ParameterizedClass hints_compression;
public volatile boolean auto_hints_cleanup_enabled = false;
@ -421,44 +421,44 @@ public class Config
public volatile boolean incremental_backups = false;
public boolean trickle_fsync = false;
@Replaces(oldName = "trickle_fsync_interval_in_kb", converter = Converters.KIBIBYTES_DATASTORAGE, deprecated = true)
public SmallestDataStorageKibibytes trickle_fsync_interval = new SmallestDataStorageKibibytes("10240KiB");
public DataStorageSpec.IntKibibytesBound trickle_fsync_interval = new DataStorageSpec.IntKibibytesBound("10240KiB");
@Replaces(oldName = "sstable_preemptive_open_interval_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public volatile SmallestDataStorageMebibytes sstable_preemptive_open_interval = new SmallestDataStorageMebibytes("50MiB");
public volatile DataStorageSpec.IntMebibytesBound sstable_preemptive_open_interval = new DataStorageSpec.IntMebibytesBound("50MiB");
public volatile boolean key_cache_migrate_during_compaction = true;
public volatile int key_cache_keys_to_save = Integer.MAX_VALUE;
@Replaces(oldName = "key_cache_size_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_LONG, deprecated = true)
public SmallestDataStorageMebibytes key_cache_size = null;
public DataStorageSpec.LongMebibytesBound key_cache_size = null;
@Replaces(oldName = "key_cache_save_period", converter = Converters.SECONDS_CUSTOM_DURATION, deprecated = true)
public volatile SmallestDurationSeconds key_cache_save_period = new SmallestDurationSeconds("4h");
public volatile DurationSpec.IntSecondsBound key_cache_save_period = new DurationSpec.IntSecondsBound("4h");
public String row_cache_class_name = "org.apache.cassandra.cache.OHCProvider";
@Replaces(oldName = "row_cache_size_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_LONG, deprecated = true)
public SmallestDataStorageMebibytes row_cache_size = new SmallestDataStorageMebibytes("0MiB");
public DataStorageSpec.LongMebibytesBound row_cache_size = new DataStorageSpec.LongMebibytesBound("0MiB");
@Replaces(oldName = "row_cache_save_period", converter = Converters.SECONDS_CUSTOM_DURATION, deprecated = true)
public volatile SmallestDurationSeconds row_cache_save_period = new SmallestDurationSeconds("0s");
public volatile DurationSpec.IntSecondsBound row_cache_save_period = new DurationSpec.IntSecondsBound("0s");
public volatile int row_cache_keys_to_save = Integer.MAX_VALUE;
@Replaces(oldName = "counter_cache_size_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_LONG, deprecated = true)
public SmallestDataStorageMebibytes counter_cache_size = null;
public DataStorageSpec.LongMebibytesBound counter_cache_size = null;
@Replaces(oldName = "counter_cache_save_period", converter = Converters.SECONDS_CUSTOM_DURATION, deprecated = true)
public volatile SmallestDurationSeconds counter_cache_save_period = new SmallestDurationSeconds("7200s");
public volatile DurationSpec.IntSecondsBound counter_cache_save_period = new DurationSpec.IntSecondsBound("7200s");
public volatile int counter_cache_keys_to_save = Integer.MAX_VALUE;
public SmallestDataStorageMebibytes paxos_cache_size = null;
public DataStorageSpec.LongMebibytesBound paxos_cache_size = null;
@Replaces(oldName = "cache_load_timeout_seconds", converter = Converters.SECONDS_DURATION, deprecated = true)
public SmallestDurationSeconds cache_load_timeout = new SmallestDurationSeconds("30s");
public DurationSpec.IntSecondsBound cache_load_timeout = new DurationSpec.IntSecondsBound("30s");
private static boolean isClientMode = false;
private static Supplier<Config> overrideLoadConfig = null;
@Replaces(oldName = "networking_cache_size_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public SmallestDataStorageMebibytes networking_cache_size;
public DataStorageSpec.IntMebibytesBound networking_cache_size;
@Replaces(oldName = "file_cache_size_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_INT, deprecated = true)
public SmallestDataStorageMebibytes file_cache_size;
public DataStorageSpec.IntMebibytesBound file_cache_size;
public boolean file_cache_enabled = Boolean.getBoolean("cassandra.file_cache_enabled");
@ -487,12 +487,12 @@ public class Config
public MemtableAllocationType memtable_allocation_type = MemtableAllocationType.heap_buffers;
public volatile boolean read_thresholds_enabled = false;
public volatile DataStorageSpec coordinator_read_size_warn_threshold = null;
public volatile DataStorageSpec coordinator_read_size_fail_threshold = null;
public volatile DataStorageSpec local_read_size_warn_threshold = null;
public volatile DataStorageSpec local_read_size_fail_threshold = null;
public volatile DataStorageSpec row_index_read_size_warn_threshold = null;
public volatile DataStorageSpec row_index_read_size_fail_threshold = null;
public volatile DataStorageSpec.LongBytesBound coordinator_read_size_warn_threshold = null;
public volatile DataStorageSpec.LongBytesBound coordinator_read_size_fail_threshold = null;
public volatile DataStorageSpec.LongBytesBound local_read_size_warn_threshold = null;
public volatile DataStorageSpec.LongBytesBound local_read_size_fail_threshold = null;
public volatile DataStorageSpec.LongBytesBound row_index_read_size_warn_threshold = null;
public volatile DataStorageSpec.LongBytesBound row_index_read_size_fail_threshold = null;
public volatile int tombstone_warn_threshold = 1000;
public volatile int tombstone_failure_threshold = 100000;
@ -500,20 +500,20 @@ public class Config
public final ReplicaFilteringProtectionOptions replica_filtering_protection = new ReplicaFilteringProtectionOptions();
@Replaces(oldName = "index_summary_capacity_in_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_LONG, deprecated = true)
public volatile SmallestDataStorageMebibytes index_summary_capacity;
public volatile DataStorageSpec.LongMebibytesBound index_summary_capacity;
@Replaces(oldName = "index_summary_resize_interval_in_minutes", converter = Converters.MINUTES_DURATION, deprecated = true)
public volatile SmallestDurationMinutes index_summary_resize_interval = new SmallestDurationMinutes("60m");
public volatile DurationSpec.IntMinutesBound index_summary_resize_interval = new DurationSpec.IntMinutesBound("60m");
@Replaces(oldName = "gc_log_threshold_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public SmallestDurationMilliseconds gc_log_threshold = new SmallestDurationMilliseconds("200ms");
public DurationSpec.IntMillisecondsBound gc_log_threshold = new DurationSpec.IntMillisecondsBound("200ms");
@Replaces(oldName = "gc_warn_threshold_in_ms", converter = Converters.MILLIS_DURATION_INT, deprecated = true)
public SmallestDurationMilliseconds gc_warn_threshold = new SmallestDurationMilliseconds("1s");
public DurationSpec.IntMillisecondsBound gc_warn_threshold = new DurationSpec.IntMillisecondsBound("1s");
// TTL for different types of trace events.
@Replaces(oldName = "tracetype_query_ttl", converter = Converters.SECONDS_DURATION, deprecated=true)
public SmallestDurationSeconds trace_type_query_ttl = new SmallestDurationSeconds("1d");
public DurationSpec.IntSecondsBound trace_type_query_ttl = new DurationSpec.IntSecondsBound("1d");
@Replaces(oldName = "tracetype_repair_ttl", converter = Converters.SECONDS_DURATION, deprecated=true)
public SmallestDurationSeconds trace_type_repair_ttl = new SmallestDurationSeconds("7d");
public DurationSpec.IntSecondsBound trace_type_repair_ttl = new DurationSpec.IntSecondsBound("7d");
/**
* Maintain statistics on whether writes achieve the ideal consistency level
@ -543,7 +543,7 @@ public class Config
* Defaults to 1/256th of the heap size or 10MiB, whichever is greater.
*/
@Replaces(oldName = "prepared_statements_cache_size_mb", converter = Converters.MEBIBYTES_DATA_STORAGE_LONG, deprecated = true)
public SmallestDataStorageMebibytes prepared_statements_cache_size = null;
public DataStorageSpec.LongMebibytesBound prepared_statements_cache_size = null;
@Replaces(oldName = "enable_user_defined_functions", converter = Converters.IDENTITY, deprecated = true)
public boolean user_defined_functions_enabled = false;
@ -595,14 +595,14 @@ public class Config
* (Only valid, if user_defined_functions_threads_enabled==true)
*/
@Replaces(oldName = "user_defined_function_warn_timeout", converter = Converters.MILLIS_DURATION_LONG, deprecated = true)
public SmallestDurationMilliseconds user_defined_functions_warn_timeout = new SmallestDurationMilliseconds("500ms");
public DurationSpec.LongMillisecondsBound user_defined_functions_warn_timeout = new DurationSpec.LongMillisecondsBound("500ms");
/**
* Time in milliseconds after a fatal UDF run-time situation is detected and action according to
* user_function_timeout_policy will take place.
* (Only valid, if user_defined_functions_threads_enabled==true)
*/
@Replaces(oldName = "user_defined_function_fail_timeout", converter = Converters.MILLIS_DURATION_LONG, deprecated = true)
public SmallestDurationMilliseconds user_defined_functions_fail_timeout = new SmallestDurationMilliseconds("1500ms");
public DurationSpec.LongMillisecondsBound user_defined_functions_fail_timeout = new DurationSpec.LongMillisecondsBound("1500ms");
/**
* Defines what to do when a UDF ran longer than user_defined_functions_fail_timeout.
* Possible options are:
@ -692,7 +692,7 @@ public class Config
*/
@Replaces(oldName = "validation_preview_purge_head_start_in_sec", converter = Converters.NEGATIVE_SECONDS_DURATION, deprecated = true)
public volatile SmallestDurationSeconds validation_preview_purge_head_start = new SmallestDurationSeconds("3600s");
public volatile DurationSpec.IntSecondsBound validation_preview_purge_head_start = new DurationSpec.IntSecondsBound("3600s");
public boolean auth_cache_warming_enabled = false;
@ -712,9 +712,9 @@ public class Config
public volatile boolean denylist_range_reads_enabled = true;
public SmallestDurationSeconds denylist_refresh = new SmallestDurationSeconds("600s");
public DurationSpec.IntSecondsBound denylist_refresh = new DurationSpec.IntSecondsBound("600s");
public SmallestDurationSeconds denylist_initial_load_retry = new SmallestDurationSeconds("5s");
public DurationSpec.IntSecondsBound denylist_initial_load_retry = new DurationSpec.IntSecondsBound("5s");
/** We cap the number of denylisted keys allowed per table to keep things from growing unbounded. Operators will
* receive warnings and only denylist_max_keys_per_table in natural query ordering will be processed on overflow.
@ -833,25 +833,25 @@ public class Config
public volatile boolean compact_tables_enabled = true;
public volatile boolean read_before_write_list_operations_enabled = true;
public volatile boolean allow_filtering_enabled = true;
public volatile DataStorageSpec collection_size_warn_threshold = null;
public volatile DataStorageSpec collection_size_fail_threshold = null;
public volatile DataStorageSpec.LongBytesBound collection_size_warn_threshold = null;
public volatile DataStorageSpec.LongBytesBound collection_size_fail_threshold = null;
public volatile int items_per_collection_warn_threshold = -1;
public volatile int items_per_collection_fail_threshold = -1;
public volatile int fields_per_udt_warn_threshold = -1;
public volatile int fields_per_udt_fail_threshold = -1;
public volatile int data_disk_usage_percentage_warn_threshold = -1;
public volatile int data_disk_usage_percentage_fail_threshold = -1;
public volatile DataStorageSpec data_disk_usage_max_disk_size = null;
public volatile DataStorageSpec.LongBytesBound data_disk_usage_max_disk_size = null;
public volatile int minimum_replication_factor_warn_threshold = -1;
public volatile int minimum_replication_factor_fail_threshold = -1;
public volatile DurationSpec streaming_state_expires = DurationSpec.inDays(3);
public volatile DataStorageSpec streaming_state_size = DataStorageSpec.inMebibytes(40);
public volatile DurationSpec.LongNanosecondsBound streaming_state_expires = new DurationSpec.LongNanosecondsBound("3d");
public volatile DataStorageSpec.LongBytesBound streaming_state_size = new DataStorageSpec.LongBytesBound("40MiB");
/** The configuration of startup checks. */
public volatile Map<StartupCheckType, Map<String, Object>> startup_checks = new HashMap<>();
public volatile DurationSpec repair_state_expires = DurationSpec.inDays(3);
public volatile DurationSpec.LongNanosecondsBound repair_state_expires = new DurationSpec.LongNanosecondsBound("3d");
public volatile int repair_state_size = 100_000;
/**
@ -950,7 +950,7 @@ public class Config
* A safety margin when purging paxos state information that has been safely replicated to a quorum.
* Data for transactions initiated within this grace period will not be expunged.
*/
public volatile DurationSpec paxos_purge_grace_period = new SmallestDurationSeconds("60s");
public volatile DurationSpec.LongSecondsBound paxos_purge_grace_period = new DurationSpec.LongSecondsBound("60s");
/**
* A safety mechanism for detecting incorrect paxos state, that may be down either to a bug or incorrect usage of LWTs
@ -1034,7 +1034,7 @@ public class Config
public volatile int max_top_size_partition_count = 10;
public volatile int max_top_tombstone_partition_count = 10;
public volatile DataStorageSpec min_tracked_partition_size_bytes = DataStorageSpec.inMebibytes(1);
public volatile DataStorageSpec.LongBytesBound min_tracked_partition_size_bytes = new DataStorageSpec.LongBytesBound("1MiB");
public volatile long min_tracked_partition_tombstone_count = 5000;
public volatile boolean top_partitions_enabled = true;

View File

@ -18,6 +18,7 @@
package org.apache.cassandra.config;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
/**
@ -37,71 +38,71 @@ public enum Converters
* able to still use the old name too. No units involved.
*/
IDENTITY(null, null, o -> o, o -> o),
MILLIS_DURATION_LONG(Long.class, SmallestDurationMilliseconds.class,
SmallestDurationMilliseconds::inMilliseconds,
MILLIS_DURATION_LONG(Long.class, DurationSpec.LongMillisecondsBound.class,
DurationSpec.LongMillisecondsBound::new,
o -> o.toMilliseconds()),
MILLIS_DURATION_INT(Integer.class, SmallestDurationMilliseconds.class,
i -> SmallestDurationMilliseconds.inMilliseconds(i),
DurationSpec::toMillisecondsAsInt),
MILLIS_DURATION_DOUBLE(Double.class, SmallestDurationMilliseconds.class,
o -> Double.isNaN(o) ? SmallestDurationMilliseconds.inMilliseconds(0) : SmallestDurationMilliseconds.inDoubleMilliseconds(o),
MILLIS_DURATION_INT(Integer.class, DurationSpec.IntMillisecondsBound.class,
DurationSpec.IntMillisecondsBound::new,
DurationSpec.IntMillisecondsBound::toMilliseconds),
MILLIS_DURATION_DOUBLE(Double.class, DurationSpec.IntMillisecondsBound.class,
o -> Double.isNaN(o) ? new DurationSpec.IntMillisecondsBound(0) :
new DurationSpec.IntMillisecondsBound(o, TimeUnit.MILLISECONDS),
o -> (double) o.toMilliseconds()),
/**
* This converter is used to support backward compatibility for parameters where in the past -1 was used as a value
* Example: credentials_update_interval_in_ms = -1 and credentials_update_interval = null are equal.
*/
MILLIS_CUSTOM_DURATION(Integer.class, SmallestDurationMilliseconds.class,
o -> o == -1 ? null : SmallestDurationMilliseconds.inMilliseconds(o),
o -> o == null ? -1 : o.toMillisecondsAsInt()),
SECONDS_DURATION(Integer.class, SmallestDurationSeconds.class,
i -> SmallestDurationSeconds.inSeconds(i),
DurationSpec::toSecondsAsInt),
NEGATIVE_SECONDS_DURATION(Integer.class, SmallestDurationSeconds.class,
o -> o < 0 ? SmallestDurationSeconds.inSeconds(0) : SmallestDurationSeconds.inSeconds(o),
DurationSpec::toSecondsAsInt),
MILLIS_CUSTOM_DURATION(Integer.class, DurationSpec.IntMillisecondsBound.class,
o -> o == -1 ? null : new DurationSpec.IntMillisecondsBound(o),
o -> o == null ? -1 : o.toMilliseconds()),
SECONDS_DURATION(Integer.class, DurationSpec.IntSecondsBound.class,
DurationSpec.IntSecondsBound::new,
DurationSpec.IntSecondsBound::toSeconds),
NEGATIVE_SECONDS_DURATION(Integer.class, DurationSpec.IntSecondsBound.class,
o -> o < 0 ? new DurationSpec.IntSecondsBound(0) : new DurationSpec.IntSecondsBound(o),
DurationSpec.IntSecondsBound::toSeconds),
/**
* This converter is used to support backward compatibility for Duration parameters where we added the opportunity
* for the users to add a unit in the parameters' values but we didn't change the names. (key_cache_save_period,
* row_cache_save_period, counter_cache_save_period)
* Example: row_cache_save_period = 0 and row_cache_save_period = 0s (quantity of 0s) are equal.
*/
SECONDS_CUSTOM_DURATION(String.class, SmallestDurationSeconds.class,
SmallestDurationSeconds::inSecondsString,
SECONDS_CUSTOM_DURATION(String.class, DurationSpec.IntSecondsBound.class,
DurationSpec.IntSecondsBound::inSecondsString,
o -> Long.toString(o.toSeconds())),
MINUTES_DURATION(Integer.class, SmallestDurationMinutes.class,
i -> SmallestDurationMinutes.inMinutes(i),
DurationSpec::toMinutesAsInt),
MEBIBYTES_DATA_STORAGE_LONG(Long.class, SmallestDataStorageMebibytes.class,
SmallestDataStorageMebibytes::inMebibytes,
DataStorageSpec::toMebibytes),
MEBIBYTES_DATA_STORAGE_INT(Integer.class, SmallestDataStorageMebibytes.class,
i -> SmallestDataStorageMebibytes.inMebibytes(i),
DataStorageSpec::toMebibytesAsInt),
KIBIBYTES_DATASTORAGE(Integer.class, SmallestDataStorageKibibytes.class,
i -> SmallestDataStorageKibibytes.inKibibytes(i),
DataStorageSpec::toKibibytesAsInt),
BYTES_DATASTORAGE(Integer.class, DataStorageSpec.class,
i -> DataStorageSpec.inBytes(i),
DataStorageSpec::toBytesAsInt),
MINUTES_DURATION(Integer.class, DurationSpec.IntMinutesBound.class,
DurationSpec.IntMinutesBound::new,
DurationSpec.IntMinutesBound::toMinutes),
MEBIBYTES_DATA_STORAGE_LONG(Long.class, DataStorageSpec.LongMebibytesBound.class,
DataStorageSpec.LongMebibytesBound::new,
DataStorageSpec.LongMebibytesBound::toMebibytes),
MEBIBYTES_DATA_STORAGE_INT(Integer.class, DataStorageSpec.IntMebibytesBound.class,
DataStorageSpec.IntMebibytesBound::new,
DataStorageSpec.IntMebibytesBound::toMebibytes),
KIBIBYTES_DATASTORAGE(Integer.class, DataStorageSpec.IntKibibytesBound.class,
DataStorageSpec.IntKibibytesBound::new,
DataStorageSpec.IntKibibytesBound::toKibibytes),
BYTES_DATASTORAGE(Integer.class, DataStorageSpec.IntBytesBound.class,
DataStorageSpec.IntBytesBound::new,
DataStorageSpec.IntBytesBound::toBytes),
/**
* This converter is used to support backward compatibility for parameters where in the past negative number was used as a value
* Example: native_transport_max_concurrent_requests_in_bytes_per_ip = -1 and native_transport_max_request_data_in_flight_per_ip = null
* are equal. All negative numbers are printed as 0 in virtual tables.
*/
BYTES_CUSTOM_DATASTORAGE(Long.class, DataStorageSpec.class,
o -> o == -1 ? null : DataStorageSpec.inBytes(o),
DataStorageSpec::toBytes),
MEBIBYTES_PER_SECOND_DATA_RATE(Integer.class, DataRateSpec.class,
i -> DataRateSpec.inMebibytesPerSecond(i),
DataRateSpec::toMebibytesPerSecondAsInt),
BYTES_CUSTOM_DATASTORAGE(Long.class, DataStorageSpec.LongBytesBound.class,
o -> o == -1 ? null : new DataStorageSpec.LongBytesBound(o),
DataStorageSpec.LongBytesBound::toBytes),
MEBIBYTES_PER_SECOND_DATA_RATE(Integer.class, DataRateSpec.IntMebibytesPerSecondBound.class,
DataRateSpec.IntMebibytesPerSecondBound::new,
DataRateSpec.IntMebibytesPerSecondBound::toMebibytesPerSecondAsInt),
/**
* This converter is a custom one to support backward compatibility for stream_throughput_outbound and
* inter_dc_stream_throughput_outbound which were provided in megatibs per second prior CASSANDRA-15234.
*/
MEGABITS_TO_MEBIBYTES_PER_SECOND_DATA_RATE(Integer.class, DataRateSpec.class,
i -> DataRateSpec.megabitsPerSecondInMebibytesPerSecond(i),
DataRateSpec::toMegabitsPerSecondAsInt);
MEGABITS_TO_MEBIBYTES_PER_SECOND_DATA_RATE(Integer.class, DataRateSpec.IntMebibytesPerSecondBound.class,
i -> DataRateSpec.IntMebibytesPerSecondBound.megabitsPerSecondInMebibytesPerSecond(i),
DataRateSpec.IntMebibytesPerSecondBound::toMegabitsPerSecondAsInt);
private final Class<?> oldType;
private final Class<?> newType;
private final Function<Object, Object> convert;

View File

@ -25,101 +25,90 @@ import java.util.stream.Collectors;
import com.google.common.primitives.Ints;
import static org.apache.cassandra.config.DataRateSpec.DataRateUnit.BYTES_PER_SECOND;
import static org.apache.cassandra.config.DataRateSpec.DataRateUnit.MEBIBYTES_PER_SECOND;
/**
* Represents a data rate type used for cassandra configuration. It supports the opportunity for the users to be able to
* add units to the confiuration parameter value. (CASSANDRA-15234)
*/
public final class DataRateSpec
public abstract class DataRateSpec
{
/**
* The Regexp used to parse the rate provided as String in cassandra.yaml.
*/
private static final Pattern BIT_RATE_UNITS_PATTERN = Pattern.compile("^(\\d+)(MiB/s|KiB/s|B/s)$");
private static final Pattern UNITS_PATTERN = Pattern.compile("^(\\d+)(MiB/s|KiB/s|B/s)$");
private final double quantity;
private final DataRateUnit unit;
public DataRateSpec(String value)
private DataRateSpec(String value)
{
//parse the string field value
Matcher matcher = BIT_RATE_UNITS_PATTERN.matcher(value);
Matcher matcher = UNITS_PATTERN.matcher(value);
if (!matcher.find())
throw new IllegalArgumentException("Invalid bit rate: " + value + " Accepted units: MiB/s, KiB/s, B/s where " +
"case matters and " + "only non-negative values are valid");
throw new IllegalArgumentException("Invalid data rate: " + value + " Accepted units: MiB/s, KiB/s, B/s where " +
"case matters and " + "only non-negative values are valid");
quantity = Long.parseLong(matcher.group(1));
quantity = (double) Long.parseLong(matcher.group(1));
unit = DataRateUnit.fromSymbol(matcher.group(2));
}
DataRateSpec(double quantity, DataRateUnit unit)
private DataRateSpec(String value, DataRateUnit minUnit, long max)
{
if (quantity < 0)
throw new IllegalArgumentException("Invalid bit rate: value must be non-negative");
this(value);
if (quantity > Long.MAX_VALUE)
throw new NumberFormatException("Invalid bit rate: value must be between 0 and Long.MAX_VALUE = 9223372036854775807");
validateQuantity(value, quantity(), unit(), minUnit, max);
}
private DataRateSpec(double quantity, DataRateUnit unit, DataRateUnit minUnit, long max)
{
this.quantity = quantity;
this.unit = unit;
validateQuantity(quantity, unit, minUnit, max);
}
/**
* Creates a {@code DataRateSpec} of the specified amount of bits per second.
*
* @param bytesPerSecond the amount of bytes per second
* @return a {@code DataRateSpec}
*/
public static DataRateSpec inBytesPerSecond(long bytesPerSecond)
private static void validateQuantity(String value, double quantity, DataRateUnit unit, DataRateUnit minUnit, long max)
{
return new DataRateSpec(bytesPerSecond, DataRateUnit.BYTES_PER_SECOND);
// negatives are not allowed by the regex pattern
if (minUnit.convert(quantity, unit) >= max)
throw new IllegalArgumentException("Invalid data rate: " + value + ". It shouldn't be more than " +
(max - 1) + " in " + minUnit.name().toLowerCase());
}
/**
* Creates a {@code DataRateSpec} of the specified amount of kibibytes per second.
*
* @param kibibytesPerSecond the amount of kibibytes per second
* @return a {@code DataRateSpec}
*/
public static DataRateSpec inKibibytesPerSecond(long kibibytesPerSecond)
private static void validateQuantity(double quantity, DataRateUnit unit, DataRateUnit minUnit, long max)
{
return new DataRateSpec(kibibytesPerSecond, DataRateUnit.KIBIBYTES_PER_SECOND);
}
/**
* Creates a {@code DataRateSpec} of the specified amount of mebibytes per second.
*
* @param mebibytesPerSecond the amount of mebibytes per second
* @return a {@code DataRateSpec}
*/
public static DataRateSpec inMebibytesPerSecond(long mebibytesPerSecond)
{
return new DataRateSpec(mebibytesPerSecond, DataRateUnit.MEBIBYTES_PER_SECOND);
}
/**
* Creates a {@code DataRateSpec} of the specified amount of mebibytes per second.
*
* @param megabitsPerSecond the amount of megabits per second
* @return a {@code DataRateSpec}
*/
public static DataRateSpec megabitsPerSecondInMebibytesPerSecond(long megabitsPerSecond)
{
final double MEBIBYTES_PER_MEGABIT = 0.119209289550781;
double mebibytesPerSecond = (double)megabitsPerSecond * MEBIBYTES_PER_MEGABIT;
return new DataRateSpec(mebibytesPerSecond, DataRateUnit.MEBIBYTES_PER_SECOND);
if (quantity < 0)
throw new IllegalArgumentException("Invalid data rate: value must be non-negative");
if (minUnit.convert(quantity, unit) >= max)
throw new IllegalArgumentException(String.format("Invalid data rate: %s %s. It shouldn't be more than %d in %s",
quantity, unit.name().toLowerCase(),
max - 1, minUnit.name().toLowerCase()));
}
// get vs no-get prefix is not consistent in the code base, but for classes involved with config parsing, it is
// imporant to be explicit about get/set as this changes how parsing is done; this class is a data-type, so is
// not nested, having get/set can confuse parsing thinking this is a nested type
/**
* @return the data rate unit assigned.
*/
public DataRateUnit getUnit()
public DataRateUnit unit()
{
return unit;
}
/**
* @return the data rate quantity.
*/
private double quantity()
{
return quantity;
}
/**
* @return the data rate in bytes per second
*/
@ -226,6 +215,99 @@ public final class DataRateSpec
return Math.round(quantity) + unit.symbol;
}
/**
* Represents a data rate used for Cassandra configuration. The bound is [0, Long.MAX_VALUE) in bytes per second.
* If the user sets a different unit, we still validate that converted to bytes per second the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class LongBytesPerSecondBound extends DataRateSpec
{
/**
* Creates a {@code DataRateSpec.LongBytesPerSecondBound} of the specified amount.
*
* @param value the data rate
*/
public LongBytesPerSecondBound(String value)
{
super(value, BYTES_PER_SECOND, Long.MAX_VALUE);
}
/**
* Creates a {@code DataRateSpec.LongBytesPerSecondBound} of the specified amount in the specified unit.
*
* @param quantity where quantity shouldn't be bigger than Long.MAX_VALUE - 1 in bytes per second
* @param unit in which the provided quantity is
*/
public LongBytesPerSecondBound(double quantity, DataRateUnit unit)
{
super(quantity, unit, BYTES_PER_SECOND, Long.MAX_VALUE);
}
/**
* Creates a {@code DataRateSpec.LongBytesPerSecondBound} of the specified amount in bytes per second.
*
* @param bytesPerSecond where bytesPerSecond shouldn't be bigger than Long.MAX_VALUE
*/
public LongBytesPerSecondBound(long bytesPerSecond)
{
this(bytesPerSecond, BYTES_PER_SECOND);
}
}
/**
* Represents a data rate used for Cassandra configuration. The bound is [0, Integer.MAX_VALUE) in mebibytes per second.
* If the user sets a different unit - we still validate that converted to mebibytes per second the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class IntMebibytesPerSecondBound extends DataRateSpec
{
/**
* Creates a {@code DataRateSpec.IntMebibytesPerSecondBound} of the specified amount with bound [0, Integer.MAX_VALUE) mebibytes per second.
*
* @param value the data rate
*/
public IntMebibytesPerSecondBound(String value)
{
super(value, MEBIBYTES_PER_SECOND, Integer.MAX_VALUE);
}
/**
* Creates a {@code DataRateSpec.IntMebibytesPerSecondBound} of the specified amount in the specified unit.
*
* @param quantity where quantity shouldn't be bigger than Integer.MAX_VALUE - 1 in mebibytes per second
* @param unit in which the provided quantity is
*/
public IntMebibytesPerSecondBound(double quantity, DataRateUnit unit)
{
super(quantity, unit, MEBIBYTES_PER_SECOND, Integer.MAX_VALUE);
}
/**
* Creates a {@code DataRateSpec.IntMebibytesPerSecondBound} of the specified amount in mebibytes per second.
*
* @param mebibytesPerSecond where mebibytesPerSecond shouldn't be bigger than Long.MAX_VALUE-1
*/
public IntMebibytesPerSecondBound(long mebibytesPerSecond)
{
this (mebibytesPerSecond, MEBIBYTES_PER_SECOND);
}
// this one should be used only for backward compatibility for stream_throughput_outbound and inter_dc_stream_throughput_outbound
// which were in megabits per second in 4.0. Do not start using it for any new properties
public static IntMebibytesPerSecondBound megabitsPerSecondInMebibytesPerSecond(long megabitsPerSecond)
{
final double MEBIBYTES_PER_MEGABIT = 0.119209289550781;
double mebibytesPerSecond = (double) megabitsPerSecond * MEBIBYTES_PER_MEGABIT;
if (megabitsPerSecond >= Integer.MAX_VALUE)
throw new IllegalArgumentException("Invalid data rate: " + megabitsPerSecond + " megabits per second; " +
"stream_throughput_outbound and inter_dc_stream_throughput_outbound" +
" should be between 0 and " + Integer.MAX_VALUE + " in megabits per second");
return new IntMebibytesPerSecondBound(mebibytesPerSecond, MEBIBYTES_PER_SECOND);
}
}
public enum DataRateUnit
{
BYTES_PER_SECOND("B/s")
@ -245,7 +327,10 @@ public final class DataRateSpec
return d / (1024.0 * 1024.0);
}
public double toMegabitsPerSecond(double d) { return (d / 125000.0); }
public double toMegabitsPerSecond(double d)
{
return (d / 125000.0);
}
public double convert(double source, DataRateUnit sourceUnit)
{
@ -366,11 +451,14 @@ public final class DataRateSpec
throw new AbstractMethodError();
}
public double toMegabitsPerSecond(double d) { throw new AbstractMethodError(); }
public double toMegabitsPerSecond(double d)
{
throw new AbstractMethodError();
}
public double convert(double source, DataRateUnit sourceUnit)
{
throw new AbstractMethodError();
}
}
}
}

View File

@ -23,11 +23,9 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.GIBIBYTES;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.BYTES;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.KIBIBYTES;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.MEBIBYTES;
@ -36,193 +34,104 @@ import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.MEBIBY
* users the opportunity to be able to provide config with a unit of their choice in cassandra.yaml as per the available
* options. (CASSANDRA-15234)
*/
public class DataStorageSpec
public abstract class DataStorageSpec
{
/**
* Immutable map that matches supported time units according to a provided smallest supported time unit
*/
private static final ImmutableMap<DataStorageUnit, ImmutableSet<DataStorageUnit>> MAP_UNITS_PER_MIN_UNIT =
ImmutableMap.of(KIBIBYTES, ImmutableSet.of(KIBIBYTES, MEBIBYTES, GIBIBYTES),
MEBIBYTES, ImmutableSet.of(MEBIBYTES, GIBIBYTES));
/**
* The Regexp used to parse the storage provided as String.
*/
private static final Pattern STORAGE_UNITS_PATTERN = Pattern.compile("^(\\d+)(GiB|MiB|KiB|B)$");
private static final Pattern UNITS_PATTERN = Pattern.compile("^(\\d+)(GiB|MiB|KiB|B)$");
private final long quantity;
private final DataStorageUnit unit;
public DataStorageSpec(String value)
private DataStorageSpec(long quantity, DataStorageUnit unit, DataStorageUnit minUnit, long max, String value)
{
//parse the string field value
Matcher matcher = STORAGE_UNITS_PATTERN.matcher(value);
if (!matcher.find())
{
throw new IllegalArgumentException("Invalid data storage: " + value + " Accepted units: B, KiB, MiB, GiB" +
" where case matters and only non-negative values are accepted");
}
quantity = Long.parseLong(matcher.group(1));
unit = DataStorageUnit.fromSymbol(matcher.group(2));
}
DataStorageSpec(long quantity, DataStorageUnit unit)
{
if (quantity < 0)
throw new IllegalArgumentException("Invalid data storage: value must be positive, but was " + quantity);
this.quantity = quantity;
this.unit = unit;
validateMinUnit(unit, minUnit, value);
validateQuantity(quantity, unit, minUnit, max);
}
public DataStorageSpec (String value, DataStorageUnit minUnit)
private DataStorageSpec(String value, DataStorageUnit minUnit)
{
if (!MAP_UNITS_PER_MIN_UNIT.containsKey(minUnit))
throw new IllegalArgumentException("Invalid smallest unit set for " + value);
//parse the string field value
Matcher matcher = STORAGE_UNITS_PATTERN.matcher(value);
Matcher matcher = UNITS_PATTERN.matcher(value);
if (matcher.find())
{
quantity = Long.parseLong(matcher.group(1));
unit = DataStorageUnit.fromSymbol(matcher.group(2));
if (!MAP_UNITS_PER_MIN_UNIT.get(minUnit).contains(unit))
throw new IllegalArgumentException("Invalid data storage: " + value + " Accepted units:" + MAP_UNITS_PER_MIN_UNIT);
// this constructor is used only by extended classes for min unit; upper bound and min unit are guarded there accordingly
}
else
{
throw new IllegalArgumentException("Invalid data storage: " + value + " Accepted units:" + MAP_UNITS_PER_MIN_UNIT.get(minUnit) +
" where case matters and only non-negative values are accepted");
throw new IllegalArgumentException("Invalid data storage: " + value + " Accepted units:" + acceptedUnits(minUnit) +
" where case matters and only non-negative values are accepted");
}
}
/**
* Creates a {@code DataStorageSpec} of the specified amount of bytes.
*
* @param bytes the amount of bytes
* @return a {@code DataStorageSpec}
*/
public static DataStorageSpec inBytes(long bytes)
private DataStorageSpec(String value, DataStorageUnit minUnit, long max)
{
return new DataStorageSpec(bytes, DataStorageUnit.BYTES);
this(value, minUnit);
validateMinUnit(unit, minUnit, value);
validateQuantity(value, quantity(), unit(), minUnit, max);
}
/**
* Creates a {@code DataStorageSpec} of the specified amount of kibibytes.
*
* @param kibibytes the amount of kibibytes
* @return a {@code DataStorageSpec}
*/
public static DataStorageSpec inKibibytes(long kibibytes)
private static void validateMinUnit(DataStorageUnit sourceUnit, DataStorageUnit minUnit, String value)
{
return new DataStorageSpec(kibibytes, KIBIBYTES);
if (sourceUnit.compareTo(minUnit) < 0)
throw new IllegalArgumentException(String.format("Invalid data storage: %s Accepted units:%s", value, acceptedUnits(minUnit)));
}
/**
* Creates a {@code DataStorageSpec} of the specified amount of mebibytes.
*
* @param mebibytes the amount of mebibytes
* @return a {@code DataStorageSpec}
*/
public static DataStorageSpec inMebibytes(long mebibytes)
private static String acceptedUnits(DataStorageUnit minUnit)
{
return new DataStorageSpec(mebibytes, MEBIBYTES);
DataStorageUnit[] units = DataStorageUnit.values();
return Arrays.toString(Arrays.copyOfRange(units, minUnit.ordinal(), units.length));
}
/**
* Creates a {@code DataStorageSpec} of the specified amount of gibibytes.
*
* @param gibibytes the amount of gibibytes
* @return a {@code DataStorageSpec}
*/
public static DataStorageSpec inGibibytes(long gibibytes)
private static void validateQuantity(String value, long quantity, DataStorageUnit sourceUnit, DataStorageUnit minUnit, long max)
{
return new DataStorageSpec(gibibytes, GIBIBYTES);
// no need to validate for negatives as they are not allowed at first place from the regex
if (minUnit.convert(quantity, sourceUnit) >= max)
throw new IllegalArgumentException("Invalid data storage: " + value + ". It shouldn't be more than " +
(max - 1) + " in " + minUnit.name().toLowerCase());
}
private static void validateQuantity(long quantity, DataStorageUnit sourceUnit, DataStorageUnit minUnit, long max)
{
if (quantity < 0)
throw new IllegalArgumentException("Invalid data storage: value must be non-negative");
if (minUnit.convert(quantity, sourceUnit) >= max)
throw new IllegalArgumentException(String.format("Invalid data storage: %d %s. It shouldn't be more than %d in %s",
quantity, sourceUnit.name().toLowerCase(),
max - 1, minUnit.name().toLowerCase()));
}
// get vs no-get prefix is not consistent in the code base, but for classes involved with config parsing, it is
// imporant to be explicit about get/set as this changes how parsing is done; this class is a data-type, so is
// not nested, having get/set can confuse parsing thinking this is a nested type
/**
* @return the data storage quantity.
*/
public long quantity()
{
return quantity;
}
/**
* @return the data storage unit.
*/
public DataStorageUnit getUnit()
public DataStorageUnit unit()
{
return unit;
}
/**
* @return the amount of data storage in bytes
*/
public long toBytes()
{
return unit.toBytes(quantity);
}
/**
* Returns the amount of data storage in bytes as an {@code int}
*
* @return the amount of data storage in bytes or {@code Integer.MAX_VALUE} if the number of bytes is too large.
*/
public int toBytesAsInt()
{
return Ints.saturatedCast(toBytes());
}
/**
* @return the amount of data storage in kibibytes
*/
public long toKibibytes()
{
return unit.toKibibytes(quantity);
}
/**
* Returns the amount of data storage in kibibytes as an {@code int}
*
* @return the amount of data storage in kibibytes or {@code Integer.MAX_VALUE} if the number of kibibytes is too large.
*/
public int toKibibytesAsInt()
{
return Ints.saturatedCast(toKibibytes());
}
/**
* @return the amount of data storage in mebibytes
*/
public long toMebibytes()
{
return unit.toMebibytes(quantity);
}
/**
* Returns the amount of data storage in mebibytes as an {@code int}
*
* @return the amount of data storage in mebibytes or {@code Integer.MAX_VALUE} if the number of mebibytes is too large.
*/
public int toMebibytesAsInt()
{
return Ints.saturatedCast(toMebibytes());
}
/**
* @return the amount of data storage in gibibytes
*/
public long toGibibytes()
{
return unit.toGibibytes(quantity);
}
/**
* Returns the amount of data storage in gibibytes as an {@code int}
*
* @return the amount of data storage in gibibytes or {@code Integer.MAX_VALUE} if the number of gibibytes is too large.
*/
public int toGibibytesAsInt()
{
return Ints.saturatedCast(toGibibytes());
}
@Override
public int hashCode()
{
@ -253,6 +162,293 @@ public class DataStorageSpec
return quantity + unit.symbol;
}
/**
* Represents a data storage quantity used for Cassandra configuration. The bound is [0, Long.MAX_VALUE) in bytes.
* If the user sets a different unit - we still validate that converted to bytes the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class LongBytesBound extends DataStorageSpec
{
/**
* Creates a {@code DataStorageSpec.LongBytesBound} of the specified amount.
*
* @param value the data storage
*/
public LongBytesBound(String value)
{
super(value, BYTES, Long.MAX_VALUE);
}
/**
* Creates a {@code DataStorageSpec.LongBytesBound} of the specified amount in the specified unit.
*
* @param quantity where quantity shouldn't be bigger than Long.MAX_VALUE - 1 in bytes
* @param unit in which the provided quantity is
*/
public LongBytesBound(long quantity, DataStorageUnit unit)
{
super(quantity, unit, BYTES, Long.MAX_VALUE, quantity + unit.symbol);
}
/**
* Creates a {@code DataStorageSpec.LongBytesBound} of the specified amount in bytes.
*
* @param bytes where bytes shouldn't be bigger than Long.MAX_VALUE-1
*/
public LongBytesBound(long bytes)
{
this(bytes, BYTES);
}
/**
* @return the amount of data storage in bytes
*/
public long toBytes()
{
return unit().toBytes(quantity());
}
}
/**
* Represents a data storage quantity used for Cassandra configuration. The bound is [0, Integer.MAX_VALUE) in bytes.
* If the user sets a different unit - we still validate that converted to bytes the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class IntBytesBound extends DataStorageSpec
{
/**
* Creates a {@code DataStorageSpec.IntBytesBound} of the specified amount.
*
* @param value the data storage
*/
public IntBytesBound(String value)
{
super(value, BYTES, Integer.MAX_VALUE);
}
/**
* Creates a {@code DataStorageSpec.IntBytesBound} of the specified amount in the specified unit.
*
* @param quantity where quantity shouldn't be bigger than Integer.MAX_VALUE - 1 in bytes
* @param unit in which the provided quantity is
*/
public IntBytesBound(long quantity, DataStorageUnit unit)
{
super(quantity, unit, BYTES, Integer.MAX_VALUE, quantity + unit.symbol);
}
/**
* Creates a {@code DataStorageSpec.IntBytesBound} of the specified amount in bytes.
*
* @param bytes where bytes shouldn't be bigger than Integer.MAX_VALUE-1
*/
public IntBytesBound(long bytes)
{
this(bytes, BYTES);
}
/**
* Returns the amount of data storage in bytes as an {@code int}
*
* @return the amount of data storage in bytes or {@code Integer.MAX_VALUE} if the number of bytes is too large.
*/
public int toBytes()
{
return Ints.saturatedCast(unit().toBytes(quantity()));
}
}
/**
* Represents a data storage quantity used for Cassandra configuration. The bound is [0, Integer.MAX_VALUE) in kibibytes.
* If the user sets a different unit - we still validate that converted to kibibytes the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class IntKibibytesBound extends DataStorageSpec
{
/**
* Creates a {@code DataStorageSpec.IntKibibytesBound} of the specified amount.
*
* @param value the data storage
*/
public IntKibibytesBound(String value)
{
super(value, KIBIBYTES, Integer.MAX_VALUE);
}
/**
* Creates a {@code DataStorageSpec.IntKibibytesBound} of the specified amount in the specified unit.
*
* @param quantity where quantity shouldn't be bigger than Integer.MAX_VALUE - 1 in kibibytes
* @param unit in which the provided quantity is
*/
public IntKibibytesBound(long quantity, DataStorageUnit unit)
{
super(quantity, unit, KIBIBYTES, Integer.MAX_VALUE, quantity + unit.symbol);
}
/**
* Creates a {@code DataStorageSpec.IntKibibytesBound} of the specified amount in kibibytes.
*
* @param kibibytes where kibibytes shouldn't be bigger than Integer.MAX_VALUE-1
*/
public IntKibibytesBound(long kibibytes)
{
this(kibibytes, KIBIBYTES);
}
/**
* Returns the amount of data storage in bytes as an {@code int}
*
* @return the amount of data storage in bytes or {@code Integer.MAX_VALUE} if the number of bytes is too large.
*/
public int toBytes()
{
return Ints.saturatedCast(unit().toBytes(quantity()));
}
/**
* Returns the amount of data storage in kibibytes as an {@code int}
*
* @return the amount of data storage in kibibytes or {@code Integer.MAX_VALUE} if the number of kibibytes is too large.
*/
public int toKibibytes()
{
return Ints.saturatedCast(unit().toKibibytes(quantity()));
}
}
/**
* Represents a data storage quantity used for Cassandra configuration. The bound is [0, Long.MAX_VALUE) in mebibytes.
* If the user sets a different unit - we still validate that converted to mebibytes the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class LongMebibytesBound extends DataStorageSpec
{
/**
* Creates a {@code DataStorageSpec.LongMebibytesBound} of the specified amount.
*
* @param value the data storage
*/
public LongMebibytesBound(String value)
{
super(value, MEBIBYTES, Long.MAX_VALUE);
}
/**
* Creates a {@code DataStorageSpec.LongMebibytesBound} of the specified amount in the specified unit.
*
* @param quantity where quantity shouldn't be bigger than Long.MAX_VALUE - 1 in mebibytes
* @param unit in which the provided quantity is
*/
public LongMebibytesBound(long quantity, DataStorageUnit unit)
{
super(quantity, unit, MEBIBYTES, Long.MAX_VALUE, quantity + unit.symbol);
}
/**
* Creates a {@code DataStorageSpec.LongMebibytesBound} of the specified amount in mebibytes.
*
* @param mebibytes where mebibytes shouldn't be bigger than Long.MAX_VALUE-1
*/
public LongMebibytesBound(long mebibytes)
{
this(mebibytes, MEBIBYTES);
}
/**
* @return the amount of data storage in bytes
*/
public long toBytes()
{
return unit().toBytes(quantity());
}
/**
* @return the amount of data storage in kibibytes
*/
public long toKibibytes()
{
return unit().toKibibytes(quantity());
}
/**
* @return the amount of data storage in mebibytes
*/
public long toMebibytes()
{
return unit().toMebibytes(quantity());
}
}
/**
* Represents a data storage quantity used for Cassandra configuration. The bound is [0, Integer.MAX_VALUE) in mebibytes.
* If the user sets a different unit - we still validate that converted to mebibytes the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class IntMebibytesBound extends DataStorageSpec
{
/**
* Creates a {@code DataStorageSpec.IntMebibytesBound} of the specified amount.
*
* @param value the data storage
*/
public IntMebibytesBound(String value)
{
super(value, MEBIBYTES, Integer.MAX_VALUE);
}
/**
* Creates a {@code DataStorageSpec.IntMebibytesBound} of the specified amount in the specified unit.
*
* @param quantity where quantity shouldn't be bigger than Integer.MAX_VALUE - 1 in mebibytes
* @param unit in which the provided quantity is
*/
public IntMebibytesBound(long quantity, DataStorageUnit unit)
{
super(quantity, unit, MEBIBYTES, Integer.MAX_VALUE, quantity + unit.symbol);
}
/**
* Creates a {@code DataStorageSpec.IntMebibytesBound} of the specified amount in mebibytes.
*
* @param mebibytes where mebibytes shouldn't be bigger than Integer.MAX_VALUE-1
*/
public IntMebibytesBound(long mebibytes)
{
this(mebibytes, MEBIBYTES);
}
/**
* Returns the amount of data storage in bytes as an {@code int}
*
* @return the amount of data storage in bytes or {@code Integer.MAX_VALUE} if the number of bytes is too large.
*/
public int toBytes()
{
return Ints.saturatedCast(unit().toBytes(quantity()));
}
/**
* Returns the amount of data storage in kibibytes as an {@code int}
*
* @return the amount of data storage in kibibytes or {@code Integer.MAX_VALUE} if the number of kibibytes is too large.
*/
public int toKibibytes()
{
return Ints.saturatedCast(unit().toKibibytes(quantity()));
}
/**
* Returns the amount of data storage in mebibytes as an {@code int}
*
* @return the amount of data storage in mebibytes or {@code Integer.MAX_VALUE} if the number of mebibytes is too large.
*/
public int toMebibytes()
{
return Ints.saturatedCast(unit().toMebibytes(quantity()));
}
}
public enum DataStorageUnit
{
BYTES("B")

File diff suppressed because it is too large Load Diff

View File

@ -24,14 +24,14 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MICROSECONDS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
/**
@ -39,77 +39,87 @@ import static java.util.concurrent.TimeUnit.SECONDS;
* users the opportunity to be able to provide config with a unit of their choice in cassandra.yaml as per the available
* options. (CASSANDRA-15234)
*/
public class DurationSpec
public abstract class DurationSpec
{
/**
* Immutable map that matches supported time units according to a provided smallest supported time unit
*/
private static final ImmutableMap<TimeUnit, ImmutableSet<TimeUnit>> MAP_UNITS_PER_MIN_UNIT =
ImmutableMap.of(MILLISECONDS, ImmutableSet.of(MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS),
SECONDS, ImmutableSet.of(SECONDS, MINUTES, HOURS, DAYS),
MINUTES, ImmutableSet.of(MINUTES, HOURS, DAYS));
/**
* The Regexp used to parse the duration provided as String.
*/
private static final Pattern TIME_UNITS_PATTERN = Pattern.compile(("^(\\d+)(d|h|s|ms|us|µs|ns|m)$"));
private static final Pattern VALUES_PATTERN = Pattern.compile(("\\d+"));
private static final Pattern UNITS_PATTERN = Pattern.compile(("^(\\d+)(d|h|s|ms|us|µs|ns|m)$"));
private final long quantity;
private final TimeUnit unit;
public DurationSpec(String value)
private DurationSpec(long quantity, TimeUnit unit, TimeUnit minUnit, long max)
{
//parse the string field value
Matcher matcher = TIME_UNITS_PATTERN.matcher(value);
this.quantity = quantity;
this.unit = unit;
validateMinUnit(unit, minUnit, quantity + " " + unit);
validateQuantity(quantity, unit, minUnit, max);
}
private DurationSpec(double quantity, TimeUnit unit, TimeUnit minUnit, long max)
{
this(Math.round(quantity), unit, minUnit, max);
}
private DurationSpec(String value, TimeUnit minUnit)
{
Matcher matcher = UNITS_PATTERN.matcher(value);
if (matcher.find())
{
quantity = Long.parseLong(matcher.group(1));
unit = fromSymbol(matcher.group(2));
// this constructor is used only by extended classes for min unit; upper bound and min unit are guarded there accordingly
}
else
{
throw new IllegalArgumentException("Invalid duration: " + value + " Accepted units: d, h, m, s, ms, us, µs," +
" ns where case matters and " + "only non-negative values");
throw new IllegalArgumentException("Invalid duration: " + value + " Accepted units:" + acceptedUnits(minUnit) +
" where case matters and only non-negative values.");
}
}
DurationSpec(long quantity, TimeUnit unit)
private DurationSpec(String value, TimeUnit minUnit, long max)
{
this(value, minUnit);
validateMinUnit(unit, minUnit, value);
validateQuantity(value, quantity(), unit(), minUnit, max);
}
private static void validateMinUnit(TimeUnit unit, TimeUnit minUnit, String value)
{
if (unit.compareTo(minUnit) < 0)
throw new IllegalArgumentException(String.format("Invalid duration: %s Accepted units:%s", value, acceptedUnits(minUnit)));
}
private static String acceptedUnits(TimeUnit minUnit)
{
TimeUnit[] units = TimeUnit.values();
return Arrays.toString(Arrays.copyOfRange(units, minUnit.ordinal(), units.length));
}
private static void validateQuantity(String value, long quantity, TimeUnit sourceUnit, TimeUnit minUnit, long max)
{
// no need to validate for negatives as they are not allowed at first place from the regex
if (minUnit.convert(quantity, sourceUnit) >= max)
throw new IllegalArgumentException("Invalid duration: " + value + ". It shouldn't be more than " +
(max - 1) + " in " + minUnit.name().toLowerCase());
}
private static void validateQuantity(long quantity, TimeUnit sourceUnit, TimeUnit minUnit, long max)
{
if (quantity < 0)
throw new IllegalArgumentException("Invalid duration " + quantity + ": value must be positive");
throw new IllegalArgumentException("Invalid duration: value must be non-negative");
this.quantity = quantity;
this.unit = unit;
}
DurationSpec(double quantity, TimeUnit unit)
{
this(Math.round(quantity), unit);
}
public DurationSpec(String value, TimeUnit minUnit)
{
if (!MAP_UNITS_PER_MIN_UNIT.containsKey(minUnit))
throw new IllegalArgumentException("Invalid smallest unit set for " + value);
Matcher matcher = TIME_UNITS_PATTERN.matcher(value);
if(matcher.find())
{
quantity = Long.parseLong(matcher.group(1));
unit = fromSymbol(matcher.group(2));
if (!MAP_UNITS_PER_MIN_UNIT.get(minUnit).contains(unit))
throw new IllegalArgumentException("Invalid duration: " + value + " Accepted units:" + MAP_UNITS_PER_MIN_UNIT.get(minUnit));
}
else
{
throw new IllegalArgumentException("Invalid duration: " + value + " Accepted units:" + MAP_UNITS_PER_MIN_UNIT.get(minUnit) +
" where case matters and only non-negative values.");
}
if (minUnit.convert(quantity, sourceUnit) >= max)
throw new IllegalArgumentException(String.format("Invalid duration: %d %s. It shouldn't be more than %d in %s",
quantity, sourceUnit.name().toLowerCase(),
max - 1, minUnit.name().toLowerCase()));
}
// get vs no-get prefix is not consistent in the code base, but for classes involved with config parsing, it is
@ -125,91 +135,6 @@ public class DurationSpec
return unit;
}
/**
* Creates a {@code DurationSpec} of the specified amount of milliseconds.
*
* @param milliseconds the amount of milliseconds
* @return a duration
*/
public static DurationSpec inMilliseconds(long milliseconds)
{
return new DurationSpec(milliseconds, MILLISECONDS);
}
public static DurationSpec inDoubleMilliseconds(double milliseconds)
{
return new DurationSpec(milliseconds, MILLISECONDS);
}
/**
* Creates a {@code DurationSpec} of the specified amount of seconds.
*
* @param seconds the amount of seconds
* @return a duration
*/
public static DurationSpec inSeconds(long seconds)
{
return new DurationSpec(seconds, SECONDS);
}
/**
* Creates a {@code DurationSpec} of the specified amount of minutes.
*
* @param minutes the amount of minutes
* @return a duration
*/
public static DurationSpec inMinutes(long minutes)
{
return new DurationSpec(minutes, MINUTES);
}
/**
* Creates a {@code DurationSpec} of the specified amount of hours.
*
* @param hours the amount of hours
* @return a duration
*/
public static DurationSpec inHours(long hours)
{
return new DurationSpec(hours, HOURS);
}
/**
* Creates a {@code DurationSpec} of the specified amount of days.
*
* @param days the amount of days
* @return a duration
*/
public static DurationSpec inDays(long days)
{
return new DurationSpec(days, DAYS);
}
/**
* Creates a {@code DurationSpec} of the specified amount of seconds. Custom method for special cases.
*
* @param value which can be in the old form only presenting the quantity or the post CASSANDRA-15234 form - a
* value consisting of quantity and unit. This method is necessary for three parameters which didn't change their
* names but only their value format. (key_cache_save_period, row_cache_save_period, counter_cache_save_period)
* @return a duration
*/
public static DurationSpec inSecondsString(String value)
{
//parse the string field value
Matcher matcher = VALUES_PATTERN.matcher(value);
long seconds;
//if the provided string value is just a number, then we create a Duration Spec value in seconds
if (matcher.matches())
{
seconds = Long.parseLong(value);
return new DurationSpec(seconds, SECONDS);
}
//otherwise we just use the standard constructors
return new DurationSpec(value);
}
/**
* @param symbol the time unit symbol
* @return the time unit associated to the specified symbol
@ -224,12 +149,12 @@ public class DurationSpec
case "s": return SECONDS;
case "ms": return MILLISECONDS;
case "us":
case "µs": return TimeUnit.MICROSECONDS;
case "µs": return MICROSECONDS;
case "ns": return TimeUnit.NANOSECONDS;
}
throw new IllegalArgumentException(String.format("Unsupported time unit: %s. Supported units are: %s",
symbol, Arrays.stream(TimeUnit.values())
.map(DurationSpec::getSymbol)
.map(DurationSpec::symbol)
.collect(Collectors.joining(", "))));
}
@ -242,104 +167,6 @@ public class DurationSpec
return targetUnit.convert(quantity, unit);
}
/**
* @return this duration in number of hours
*/
public long toHours()
{
return unit.toHours(quantity);
}
/**
* Returns this duration in number of minutes as an {@code int}
*
* @return this duration in number of minutes or {@code Integer.MAX_VALUE} if the number of minutes is too large.
*/
public int toHoursAsInt()
{
return Ints.saturatedCast(toHours());
}
/**
* @return this duration in number of minutes
*/
public long toMinutes()
{
return unit.toMinutes(quantity);
}
/**
* Returns this duration in number of minutes as an {@code int}
*
* @return this duration in number of minutes or {@code Integer.MAX_VALUE} if the number of minutes is too large.
*/
public int toMinutesAsInt()
{
return Ints.saturatedCast(toMinutes());
}
/**
* @return this duration in number of seconds
*/
public long toSeconds()
{
return unit.toSeconds(quantity);
}
/**
* Returns this duration in number of seconds as an {@code int}
*
* @return this duration in number of seconds or {@code Integer.MAX_VALUE} if the number of seconds is too large.
*/
public int toSecondsAsInt()
{
return Ints.saturatedCast(toSeconds());
}
/**
* @return this duration in number of nanoseconds
*/
public long toNanoseconds()
{
return unit.toNanos(quantity);
}
/**
* Returns this duration in number of nanoseconds as an {@code int}
*
* @return this duration in number of nanoseconds or {@code Integer.MAX_VALUE} if the number of nanoseconds is too large.
*/
public int toNanosecondsAsInt()
{
return Ints.saturatedCast(toNanoseconds());
}
/**
* @return this duration in number of milliseconds
*/
public long toMilliseconds()
{
return unit.toMillis(quantity);
}
/**
* @return the duration value in milliseconds
*/
public static long toMilliseconds(DurationSpec quantity)
{
return quantity.toMilliseconds();
}
/**
* Returns this duration in number of milliseconds as an {@code int}
*
* @return this duration in number of milliseconds or {@code Integer.MAX_VALUE} if the number of milliseconds is too large.
*/
public int toMillisecondsAsInt()
{
return Ints.saturatedCast(toMilliseconds());
}
@Override
public int hashCode()
{
@ -368,7 +195,7 @@ public class DurationSpec
@Override
public String toString()
{
return quantity + getSymbol(unit);
return quantity + symbol(unit);
}
/**
@ -377,7 +204,10 @@ public class DurationSpec
* @param unit the time unit
* @return the time unit symbol
*/
static String getSymbol(TimeUnit unit)
// get vs no-get prefix is not consistent in the code base, but for classes involved with config parsing, it is
// imporant to be explicit about get/set as this changes how parsing is done; this class is a data-type, so is
// not nested, having get/set can confuse parsing thinking this is a nested type
static String symbol(TimeUnit unit)
{
switch (unit)
{
@ -391,4 +221,387 @@ public class DurationSpec
}
throw new AssertionError();
}
/**
* Represents a duration used for Cassandra configuration. The bound is [0, Long.MAX_VALUE) in nanoseconds.
* If the user sets a different unit - we still validate that converted to nanoseconds the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class LongNanosecondsBound extends DurationSpec
{
/**
* Creates a {@code DurationSpec.LongNanosecondsBound} of the specified amount.
* The bound is [0, Long.MAX_VALUE) in nanoseconds.
*
* @param value the duration
*/
public LongNanosecondsBound(String value)
{
super(value, NANOSECONDS, Long.MAX_VALUE);
}
/**
* Creates a {@code DurationSpec.LongNanosecondsBound} of the specified amount in the specified unit.
* The bound is [0, Long.MAX_VALUE) in nanoseconds.
*
* @param quantity where quantity shouldn't be bigger than Long.MAX_VALUE - 1 in nanoseconds
* @param unit in which the provided quantity is
*/
public LongNanosecondsBound(long quantity, TimeUnit unit)
{
super(quantity, unit, NANOSECONDS, Long.MAX_VALUE);
}
/**
* Creates a {@code DurationSpec.LongNanosecondsBound} of the specified amount in nanoseconds.
* The bound is [0, Long.MAX_VALUE) in nanoseconds.
*
* @param nanoseconds where nanoseconds shouldn't be bigger than Long.MAX_VALUE-1
*/
public LongNanosecondsBound(long nanoseconds)
{
this(nanoseconds, NANOSECONDS);
}
/**
* @return this duration in number of nanoseconds
*/
public long toNanoseconds()
{
return unit().toNanos(quantity());
}
}
/**
* Represents a duration used for Cassandra configuration. The bound is [0, Long.MAX_VALUE) in milliseconds.
* If the user sets a different unit - we still validate that converted to milliseconds the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class LongMillisecondsBound extends DurationSpec
{
/**
* Creates a {@code DurationSpec.LongMillisecondsBound} of the specified amount.
* The bound is [0, Long.MAX_VALUE) in milliseconds.
*
* @param value the duration
*/
public LongMillisecondsBound(String value)
{
super(value, MILLISECONDS, Long.MAX_VALUE);
}
/**
* Creates a {@code DurationSpec.LongMillisecondsBound} of the specified amount in the specified unit.
* The bound is [0, Long.MAX_VALUE) in milliseconds.
*
* @param quantity where quantity shouldn't be bigger than Long.MAX_VALUE - 1 in milliseconds
* @param unit in which the provided quantity is
*/
public LongMillisecondsBound(long quantity, TimeUnit unit)
{
super(quantity, unit, MILLISECONDS, Long.MAX_VALUE);
}
/**
* Creates a {@code DurationSpec.LongMillisecondsBound} of the specified amount in milliseconds.
* The bound is [0, Long.MAX_VALUE) in milliseconds.
*
* @param milliseconds where milliseconds shouldn't be bigger than Long.MAX_VALUE-1
*/
public LongMillisecondsBound(long milliseconds)
{
this(milliseconds, MILLISECONDS);
}
/**
* @return this duration in number of milliseconds
*/
public long toMilliseconds()
{
return unit().toMillis(quantity());
}
}
/**
* Represents a duration used for Cassandra configuration. The bound is [0, Long.MAX_VALUE) in seconds.
* If the user sets a different unit - we still validate that converted to seconds the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class LongSecondsBound extends DurationSpec
{
/**
* Creates a {@code DurationSpec.LongSecondsBound} of the specified amount.
* The bound is [0, Long.MAX_VALUE) in seconds.
*
* @param value the duration
*/
public LongSecondsBound(String value)
{
super(value, SECONDS, Long.MAX_VALUE);
}
/**
* Creates a {@code DurationSpec.LongSecondsBound} of the specified amount in the specified unit.
* The bound is [0, Long.MAX_VALUE) in seconds.
*
* @param quantity where quantity shouldn't be bigger than Long.MAX_VALUE - 1 in seconds
* @param unit in which the provided quantity is
*/
public LongSecondsBound(long quantity, TimeUnit unit)
{
super(quantity, unit, SECONDS, Long.MAX_VALUE);
}
/**
* Creates a {@code DurationSpec.LongSecondsBound} of the specified amount in seconds.
* The bound is [0, Long.MAX_VALUE) in seconds.
*
* @param seconds where seconds shouldn't be bigger than Long.MAX_VALUE-1
*/
public LongSecondsBound(long seconds)
{
this(seconds, SECONDS);
}
/**
* @return this duration in number of milliseconds
*/
public long toMilliseconds()
{
return unit().toMillis(quantity());
}
/**
* @return this duration in number of seconds
*/
public long toSeconds()
{
return unit().toSeconds(quantity());
}
}
/**
* Represents a duration used for Cassandra configuration. The bound is [0, Integer.MAX_VALUE) in minutes.
* If the user sets a different unit - we still validate that converted to minutes the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class IntMinutesBound extends DurationSpec
{
/**
* Creates a {@code DurationSpec.IntMinutesBound} of the specified amount. The bound is [0, Integer.MAX_VALUE) in minutes.
* The bound is [0, Integer.MAX_VALUE) in minutes.
*
* @param value the duration
*/
public IntMinutesBound(String value)
{
super(value, MINUTES, Integer.MAX_VALUE);
}
/**
* Creates a {@code DurationSpec.IntMinutesBound} of the specified amount in the specified unit.
* The bound is [0, Integer.MAX_VALUE) in minutes.
*
* @param quantity where quantity shouldn't be bigger than Integer.MAX_VALUE - 1 in minutes
* @param unit in which the provided quantity is
*/
public IntMinutesBound(long quantity, TimeUnit unit)
{
super(quantity, unit, MINUTES, Integer.MAX_VALUE);
}
/**
* Creates a {@code DurationSpec.IntMinutesBound} of the specified amount in minutes.
* The bound is [0, Integer.MAX_VALUE) in minutes.
*
* @param minutes where minutes shouldn't be bigger than Integer.MAX_VALUE-1
*/
public IntMinutesBound(long minutes)
{
this(minutes, MINUTES);
}
/**
* Returns this duration in number of milliseconds as an {@code int}
*
* @return this duration in number of milliseconds or {@code Integer.MAX_VALUE} if the number of milliseconds is too large.
*/
public int toMilliseconds()
{
return Ints.saturatedCast(unit().toMillis(quantity()));
}
/**
* Returns this duration in number of seconds as an {@code int}
*
* @return this duration in number of seconds or {@code Integer.MAX_VALUE} if the number of seconds is too large.
*/
public int toSeconds()
{
return Ints.saturatedCast(unit().toSeconds(quantity()));
}
/**
* Returns this duration in number of minutes as an {@code int}
*
* @return this duration in number of minutes or {@code Integer.MAX_VALUE} if the number of minutes is too large.
*/
public int toMinutes()
{
return Ints.saturatedCast(unit().toMinutes(quantity()));
}
}
/**
* Represents a duration used for Cassandra configuration. The bound is [0, Integer.MAX_VALUE) in seconds.
* If the user sets a different unit - we still validate that converted to seconds the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class IntSecondsBound extends DurationSpec
{
private static final Pattern VALUES_PATTERN = Pattern.compile(("\\d+"));
/**
* Creates a {@code DurationSpec.IntSecondsBound} of the specified amount. The bound is [0, Integer.MAX_VALUE) in seconds.
* The bound is [0, Integer.MAX_VALUE) in seconds.
*
* @param value the duration
*/
public IntSecondsBound(String value)
{
super(value, SECONDS, Integer.MAX_VALUE);
}
/**
* Creates a {@code DurationSpec.IntSecondsBound} of the specified amount in the specified unit.
* The bound is [0, Integer.MAX_VALUE) in seconds.
*
* @param quantity where quantity shouldn't be bigger than Integer.MAX_VALUE - 1 in seconds
* @param unit in which the provided quantity is
*/
public IntSecondsBound(long quantity, TimeUnit unit)
{
super(quantity, unit, SECONDS, Integer.MAX_VALUE);
}
/**
* Creates a {@code DurationSpec.IntSecondsBound} of the specified amount in seconds.
* The bound is [0, Integer.MAX_VALUE) in seconds.
*
* @param seconds where seconds shouldn't be bigger than Integer.MAX_VALUE-1
*/
public IntSecondsBound(long seconds)
{
this(seconds, SECONDS);
}
/**
* Creates a {@code DurationSpec.IntSecondsBound} of the specified amount in seconds, expressed either as the
* number of seconds without unit, or as a regular quantity with unit.
* Used in the Converters for a few parameters which changed only type, but not names
* The bound is [0, Integer.MAX_VALUE) in seconds.
*
* @param value where value shouldn't be bigger than Integer.MAX_VALUE-1 in seconds
*/
public static IntSecondsBound inSecondsString(String value)
{
//parse the string field value
Matcher matcher = VALUES_PATTERN.matcher(value);
long seconds;
//if the provided string value is just a number, then we create a IntSecondsBound value in seconds
if (matcher.matches())
{
seconds = Integer.parseInt(value);
return new IntSecondsBound(seconds, TimeUnit.SECONDS);
}
//otherwise we just use the standard constructors
return new IntSecondsBound(value);
}
/**
* Returns this duration in number of milliseconds as an {@code int}
*
* @return this duration in number of milliseconds or {@code Integer.MAX_VALUE} if the number of milliseconds is too large.
*/
public int toMilliseconds()
{
return Ints.saturatedCast(unit().toMillis(quantity()));
}
/**
* Returns this duration in number of seconds as an {@code int}
*
* @return this duration in number of seconds or {@code Integer.MAX_VALUE} if the number of seconds is too large.
*/
public int toSeconds()
{
return Ints.saturatedCast(unit().toSeconds(quantity()));
}
}
/**
* Represents a duration used for Cassandra configuration. The bound is [0, Integer.MAX_VALUE) in milliseconds.
* If the user sets a different unit - we still validate that converted to milliseconds the quantity will not exceed
* that upper bound. (CASSANDRA-17571)
*/
public final static class IntMillisecondsBound extends DurationSpec
{
/**
* Creates a {@code DurationSpec.IntMillisecondsBound} of the specified amount. The bound is [0, Integer.MAX_VALUE) in milliseconds.
* The bound is [0, Integer.MAX_VALUE) in milliseconds.
*
* @param value the duration
*/
public IntMillisecondsBound(String value)
{
super(value, MILLISECONDS, Integer.MAX_VALUE);
}
/**
* Creates a {@code DurationSpec.IntMillisecondsBound} of the specified amount in the specified unit.
* The bound is [0, Integer.MAX_VALUE) in milliseconds.
*
* @param quantity where quantity shouldn't be bigger than Integer.MAX_VALUE - 1 in milliseconds
* @param unit in which the provided quantity is
*/
public IntMillisecondsBound(long quantity, TimeUnit unit)
{
super(quantity, unit, MILLISECONDS, Integer.MAX_VALUE);
}
/**
* Creates a {@code DurationSpec.IntMillisecondsBound} of the specified amount in milliseconds.
* The bound is [0, Integer.MAX_VALUE) in milliseconds.
*
* @param milliseconds where milliseconds shouldn't be bigger than Integer.MAX_VALUE-1
*/
public IntMillisecondsBound(long milliseconds)
{
this(milliseconds, MILLISECONDS);
}
/**
* Below constructor is used only for backward compatibility for the old commitlog_sync_group_window_in_ms before 4.1
* Creates a {@code DurationSpec.IntMillisecondsBound} of the specified amount in the specified unit.
*
* @param quantity where quantity shouldn't be bigger than Intetger.MAX_VALUE - 1 in milliseconds
* @param unit in which the provided quantity is
*/
public IntMillisecondsBound(double quantity, TimeUnit unit)
{
super(quantity, unit, MILLISECONDS, Integer.MAX_VALUE);
}
/**
* Returns this duration in number of milliseconds as an {@code int}
*
* @return this duration in number of milliseconds or {@code Integer.MAX_VALUE} if the number of milliseconds is too large.
*/
public int toMilliseconds()
{
return Ints.saturatedCast(unit().toMillis(quantity()));
}
}
}

View File

@ -509,19 +509,19 @@ public class GuardrailsOptions implements GuardrailsConfig
@Override
@Nullable
public DataStorageSpec getCollectionSizeWarnThreshold()
public DataStorageSpec.LongBytesBound getCollectionSizeWarnThreshold()
{
return config.collection_size_warn_threshold;
}
@Override
@Nullable
public DataStorageSpec getCollectionSizeFailThreshold()
public DataStorageSpec.LongBytesBound getCollectionSizeFailThreshold()
{
return config.collection_size_fail_threshold;
}
public void setCollectionSizeThreshold(@Nullable DataStorageSpec warn, @Nullable DataStorageSpec fail)
public void setCollectionSizeThreshold(@Nullable DataStorageSpec.LongBytesBound warn, @Nullable DataStorageSpec.LongBytesBound fail)
{
validateSizeThreshold(warn, fail, false, "collection_size");
updatePropertyWithLogging("collection_size_warn_threshold",
@ -609,12 +609,12 @@ public class GuardrailsOptions implements GuardrailsConfig
}
@Override
public DataStorageSpec getDataDiskUsageMaxDiskSize()
public DataStorageSpec.LongBytesBound getDataDiskUsageMaxDiskSize()
{
return config.data_disk_usage_max_disk_size;
}
public void setDataDiskUsageMaxDiskSize(@Nullable DataStorageSpec diskSize)
public void setDataDiskUsageMaxDiskSize(@Nullable DataStorageSpec.LongBytesBound diskSize)
{
validateDataDiskUsageMaxDiskSize(diskSize);
updatePropertyWithLogging("data_disk_usage_max_disk_size",
@ -738,7 +738,7 @@ public class GuardrailsOptions implements GuardrailsConfig
}
}
private static void validateSize(DataStorageSpec size, boolean allowZero, String name)
private static void validateSize(DataStorageSpec.LongBytesBound size, boolean allowZero, String name)
{
if (size == null)
return;
@ -749,14 +749,14 @@ public class GuardrailsOptions implements GuardrailsConfig
name));
}
private static void validateSizeThreshold(DataStorageSpec warn, DataStorageSpec fail, boolean allowZero, String name)
private static void validateSizeThreshold(DataStorageSpec.LongBytesBound warn, DataStorageSpec.LongBytesBound fail, boolean allowZero, String name)
{
validateSize(warn, allowZero, name + "_warn_threshold");
validateSize(fail, allowZero, name + "_fail_threshold");
validateWarnLowerThanFail(warn, fail, name);
}
private static void validateWarnLowerThanFail(DataStorageSpec warn, DataStorageSpec fail, String name)
private static void validateWarnLowerThanFail(DataStorageSpec.LongBytesBound warn, DataStorageSpec.LongBytesBound fail, String name)
{
if (warn == null || fail == null)
return;
@ -790,7 +790,7 @@ public class GuardrailsOptions implements GuardrailsConfig
return consistencyLevels.isEmpty() ? Collections.emptySet() : Sets.immutableEnumSet(consistencyLevels);
}
private static void validateDataDiskUsageMaxDiskSize(DataStorageSpec maxDiskSize)
private static void validateDataDiskUsageMaxDiskSize(DataStorageSpec.LongBytesBound maxDiskSize)
{
if (maxDiskSize == null)
return;

View File

@ -1,55 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.config;
/**
* Wrapper class for Cassandra data storage configuration parameters which are internally represented in Kibibytes. In order
* not to lose precision while converting to smaller units (until we migrate those parameters to use internally the smallest
* supported unit) we restrict those parameters to use only kibibytes or larger units. (CASSANDRA-15234)
*/
public final class SmallestDataStorageKibibytes extends DataStorageSpec
{
/**
* Creates a {@code SmallestDataStorageKibibytes} of the specified amount of seconds and provides the smallest
* required unit of Kibibytes for the respective parameter of type {@code SmallestDurationSeconds}.
*
* @param value the data storage
*
*/
public SmallestDataStorageKibibytes(String value)
{
super(value, DataStorageSpec.DataStorageUnit.KIBIBYTES);
}
private SmallestDataStorageKibibytes(long quantity, DataStorageSpec.DataStorageUnit unit)
{
super(quantity, unit);
}
/**
* Creates a {@code SmallestDataStorageKibibytes} of the specified amount of kibibytes.
*
* @param kibibytes the amount of kibibytes
* @return a data storage
*/
public static SmallestDataStorageKibibytes inKibibytes(long kibibytes)
{
return new SmallestDataStorageKibibytes(kibibytes, DataStorageSpec.DataStorageUnit.KIBIBYTES);
}
}

View File

@ -1,66 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.config;
/**
* Wrapper class for Cassandra data storage configuration parameters which are internally represented in mebibytes. In order
* not to lose precision while converting to smaller units (until we migrate those parameters to use internally the smallest
* supported unit) we restrict those parameters to use only mebibytes or larger units. (CASSANDRA-15234)
*/
public final class SmallestDataStorageMebibytes extends DataStorageSpec
{
/**
* Creates a {@code SmallestDataStoragemebibytes} of the specified amount of seconds and provides the smallest
* required unit of mebibytes for the respective parameter of type {@code SmallestDurationSeconds}.
*
* @param value the data storage
*
*/
public SmallestDataStorageMebibytes(String value)
{
super(value, DataStorageSpec.DataStorageUnit.MEBIBYTES);
}
private SmallestDataStorageMebibytes(long quantity, DataStorageSpec.DataStorageUnit unit)
{
super(quantity, unit);
}
/**
* Creates a {@code SmallestDataStorageMebibytes} of the specified amount of mebibytes.
*
* @param mebibytes the amount of mebibytes
* @return a data storage
*/
public static SmallestDataStorageMebibytes inMebibytes(long mebibytes)
{
return new SmallestDataStorageMebibytes(mebibytes, DataStorageSpec.DataStorageUnit.MEBIBYTES);
}
/**
* Creates a {@code SmallestDataStorageMebibytes} of the specified amount of bytes.
*
* @param bytes the amount of bytes
* @return a data storage
*/
public static SmallestDataStorageMebibytes inBytes(long bytes)
{
return new SmallestDataStorageMebibytes(bytes, DataStorageSpec.DataStorageUnit.BYTES);
}
}

View File

@ -1,69 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.config;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
/**
* Wrapper class for Cassandra duration configuration parameters which are internally represented in Milliseconds. In order
* not to lose precision while converting to smaller units (until we migrate those parameters to use internally the smallest
* supported unit) we restrict those parameters to use only Milliseconds or larger units. (CASSANDRA-15234)
*/
public final class SmallestDurationMilliseconds extends DurationSpec
{
/**
* Creates a {@code SmallestDurationMilliseconds} of the specified amount of milliseconds and provides the smallest
* required unit of milliseconds for the respective parameter of type {@code SmallestDurationMilliseconds}.
*
* @param value the duration
*
*/
public SmallestDurationMilliseconds(String value)
{
super(value, TimeUnit.MILLISECONDS);
}
private SmallestDurationMilliseconds(long quantity, TimeUnit unit)
{
super(quantity, unit);
}
private SmallestDurationMilliseconds(double quantity, TimeUnit unit)
{
super(quantity, unit);
}
/**
* Creates a {@code SmallestDurationMilliseconds} of the specified amount of milliseconds.
*
* @param milliseconds the amount of milliseconds
* @return a duration
*/
public static SmallestDurationMilliseconds inMilliseconds(long milliseconds)
{
return new SmallestDurationMilliseconds(milliseconds, TimeUnit.MILLISECONDS);
}
public static SmallestDurationMilliseconds inDoubleMilliseconds(double milliseconds)
{
return new SmallestDurationMilliseconds(milliseconds, MILLISECONDS);
}
}

View File

@ -1,57 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.config;
import java.util.concurrent.TimeUnit;
/**
* Wrapper class for Cassandra duration configuration parameters which are internally represented in Minuts. In order
* not to lose precision while converting to smaller units (until we migrate those parameters to use internally the smallest
* supported unit) we restrict those parameters to use only Minutes or larger units. (CASSANDRA-15234)
*/
public final class SmallestDurationMinutes extends DurationSpec
{
/**
* Creates a {@code SmallestDurationMinutes} of the specified amount of minutes and provides the smallest
* required unit of minutes for the respective parameter of type {@code SmallestDurationMinutes}.
*
* @param value the duration
*
*/
public SmallestDurationMinutes(String value)
{
super(value, TimeUnit.MINUTES);
}
private SmallestDurationMinutes(long quantity, TimeUnit unit)
{
super(quantity, unit);
}
/**
* Creates a {@code SmallestDurationMinutes} of the specified amount of minutes.
*
* @param minutes the amount of minutes
* @return a duration
*/
public static SmallestDurationMinutes inMinutes(long minutes)
{
return new SmallestDurationMinutes(minutes, TimeUnit.MINUTES);
}
}

View File

@ -1,86 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.config;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Wrapper class for Cassandra duration configuration parameters which are internally represented in Seconds. In order
* not to lose precision while converting to smaller units (until we migrate those parameters to use internally the smallest
* supported unit) we restrict those parameters to use only Seconds or larger units. (CASSANDRA-15234)
*/
public final class SmallestDurationSeconds extends DurationSpec
{
private static final Pattern VALUES_PATTERN = Pattern.compile(("\\d+"));
/**
* Creates a {@code SmallestDurationSeconds} of the specified amount of seconds and provides the smallest
* required unit of seconds for the respective parameter of type {@code SmallestDurationSeconds}.
*
* @param value the duration
*
*/
public SmallestDurationSeconds(String value)
{
super(value, TimeUnit.SECONDS);
}
private SmallestDurationSeconds(long quantity, TimeUnit unit)
{
super(quantity, unit);
}
/**
* Creates a {@code SmallestDurationSeconds} of the specified amount of seconds.
*
* @param seconds the amount of seconds
* @return a duration
*/
public static SmallestDurationSeconds inSeconds(long seconds)
{
return new SmallestDurationSeconds(seconds, TimeUnit.SECONDS);
}
/**
* Creates a {@code SmallestDurationSeconds} of the specified amount of seconds. Custom method for special cases.
*
* @param value which can be in the old form only presenting the quantity or the post CASSANDRA-15234 form - a
* value consisting of quantity and unit. This method is necessary for three parameters which didn't change their
* names but only their value format. (key_cache_save_period, row_cache_save_period, counter_cache_save_period)
* @return a duration
*/
public static SmallestDurationSeconds inSecondsString(String value)
{
//parse the string field value
Matcher matcher = VALUES_PATTERN.matcher(value);
long seconds;
//if the provided string value is just a number, then we create a Duration Spec value in seconds
if (matcher.matches())
{
seconds = Long.parseLong(value);
return new SmallestDurationSeconds(seconds, TimeUnit.SECONDS);
}
//otherwise we just use the standard constructors
return new SmallestDurationSeconds(value);
}
}

View File

@ -296,7 +296,7 @@ public abstract class QueryOptions
private final long warnThresholdBytes;
private final long abortThresholdBytes;
public DefaultReadThresholds(DataStorageSpec warnThreshold, DataStorageSpec abortThreshold)
public DefaultReadThresholds(DataStorageSpec.LongBytesBound warnThreshold, DataStorageSpec.LongBytesBound abortThreshold)
{
this.warnThresholdBytes = warnThreshold == null ? -1 : warnThreshold.toBytes();
this.abortThresholdBytes = abortThreshold == null ? -1 : abortThreshold.toBytes();

View File

@ -2002,7 +2002,7 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean, Memtable.Owner
/**
* @param ephemeral If this flag is set to true, the snapshot will be cleaned during next startup
*/
public TableSnapshot snapshotWithoutMemtable(String snapshotName, Predicate<SSTableReader> predicate, boolean ephemeral, DurationSpec ttl, RateLimiter rateLimiter, Instant creationTime)
public TableSnapshot snapshotWithoutMemtable(String snapshotName, Predicate<SSTableReader> predicate, boolean ephemeral, DurationSpec.IntSecondsBound ttl, RateLimiter rateLimiter, Instant creationTime)
{
if (ephemeral && ttl != null)
{
@ -2032,7 +2032,7 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean, Memtable.Owner
return createSnapshot(snapshotName, ephemeral, ttl, snapshottedSSTables, creationTime);
}
protected TableSnapshot createSnapshot(String tag, boolean ephemeral, DurationSpec ttl, Set<SSTableReader> sstables, Instant creationTime) {
protected TableSnapshot createSnapshot(String tag, boolean ephemeral, DurationSpec.IntSecondsBound ttl, Set<SSTableReader> sstables, Instant creationTime) {
Set<File> snapshotDirs = sstables.stream()
.map(s -> Directories.getSnapshotDirectory(s.descriptor, tag).toAbsolute())
.filter(dir -> !Directories.isSecondaryIndexFolder(dir)) // Remove secondary index subdirectory
@ -2187,7 +2187,7 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean, Memtable.Owner
return snapshot(snapshotName, null);
}
public TableSnapshot snapshot(String snapshotName, DurationSpec ttl)
public TableSnapshot snapshot(String snapshotName, DurationSpec.IntSecondsBound ttl)
{
return snapshot(snapshotName, false, ttl, null, now());
}
@ -2201,7 +2201,7 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean, Memtable.Owner
* @param rateLimiter Rate limiter for hardlinks-per-second
* @param creationTime time when this snapshot was taken
*/
public TableSnapshot snapshot(String snapshotName, boolean skipMemtable, DurationSpec ttl, RateLimiter rateLimiter, Instant creationTime)
public TableSnapshot snapshot(String snapshotName, boolean skipMemtable, DurationSpec.IntSecondsBound ttl, RateLimiter rateLimiter, Instant creationTime)
{
return snapshot(snapshotName, null, false, skipMemtable, ttl, rateLimiter, creationTime);
}
@ -2223,7 +2223,7 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean, Memtable.Owner
* @param rateLimiter Rate limiter for hardlinks-per-second
* @param creationTime time when this snapshot was taken
*/
public TableSnapshot snapshot(String snapshotName, Predicate<SSTableReader> predicate, boolean ephemeral, boolean skipMemtable, DurationSpec ttl, RateLimiter rateLimiter, Instant creationTime)
public TableSnapshot snapshot(String snapshotName, Predicate<SSTableReader> predicate, boolean ephemeral, boolean skipMemtable, DurationSpec.IntSecondsBound ttl, RateLimiter rateLimiter, Instant creationTime)
{
if (!skipMemtable)
{

View File

@ -230,7 +230,7 @@ public class Keyspace
* @param rateLimiter Rate limiter for hardlinks-per-second
* @throws IOException if the column family doesn't exist
*/
public void snapshot(String snapshotName, String columnFamilyName, boolean skipFlush, DurationSpec ttl, RateLimiter rateLimiter, Instant creationTime) throws IOException
public void snapshot(String snapshotName, String columnFamilyName, boolean skipFlush, DurationSpec.IntSecondsBound ttl, RateLimiter rateLimiter, Instant creationTime) throws IOException
{
assert snapshotName != null;
boolean tookSnapShot = false;

View File

@ -653,7 +653,7 @@ public abstract class ReadCommand extends AbstractReadQuery
}
}
private boolean shouldTrackSize(DataStorageSpec warnThresholdBytes, DataStorageSpec abortThresholdBytes)
private boolean shouldTrackSize(DataStorageSpec.LongBytesBound warnThresholdBytes, DataStorageSpec.LongBytesBound abortThresholdBytes)
{
return trackWarnings
&& !SchemaConstants.isSystemKeyspace(metadata().keyspace)
@ -662,8 +662,8 @@ public abstract class ReadCommand extends AbstractReadQuery
private UnfilteredPartitionIterator withQuerySizeTracking(UnfilteredPartitionIterator iterator)
{
DataStorageSpec warnThreshold = DatabaseDescriptor.getLocalReadSizeWarnThreshold();
DataStorageSpec failThreshold = DatabaseDescriptor.getLocalReadSizeFailThreshold();
DataStorageSpec.LongBytesBound warnThreshold = DatabaseDescriptor.getLocalReadSizeWarnThreshold();
DataStorageSpec.LongBytesBound failThreshold = DatabaseDescriptor.getLocalReadSizeFailThreshold();
if (!shouldTrackSize(warnThreshold, failThreshold))
return iterator;
final long warnBytes = warnThreshold == null ? -1 : warnThreshold.toBytes();

View File

@ -356,8 +356,8 @@ public class RowIndexEntry<T> implements IMeasurableMemory
if (command == null || SchemaConstants.isSystemKeyspace(command.metadata().keyspace) || !DatabaseDescriptor.getReadThresholdsEnabled())
return;
DataStorageSpec warnThreshold = DatabaseDescriptor.getRowIndexReadSizeWarnThreshold();
DataStorageSpec failThreshold = DatabaseDescriptor.getRowIndexReadSizeFailThreshold();
DataStorageSpec.LongBytesBound warnThreshold = DatabaseDescriptor.getRowIndexReadSizeWarnThreshold();
DataStorageSpec.LongBytesBound failThreshold = DatabaseDescriptor.getRowIndexReadSizeFailThreshold();
if (warnThreshold == null && failThreshold == null)
return;

View File

@ -920,7 +920,7 @@ public final class Guardrails implements GuardrailsMBean
return set.stream().map(ConsistencyLevel::valueOf).collect(Collectors.toSet());
}
private static Long sizeToBytes(@Nullable DataStorageSpec size)
private static Long sizeToBytes(@Nullable DataStorageSpec.LongBytesBound size)
{
return size == null ? -1 : size.toBytes();
}
@ -930,8 +930,8 @@ public final class Guardrails implements GuardrailsMBean
return size == null ? null : size.toString();
}
private static DataStorageSpec sizeFromString(@Nullable String size)
private static DataStorageSpec.LongBytesBound sizeFromString(@Nullable String size)
{
return StringUtils.isEmpty(size) ? null : new DataStorageSpec(size);
return StringUtils.isEmpty(size) ? null : new DataStorageSpec.LongBytesBound(size);
}
}

View File

@ -227,13 +227,13 @@ public interface GuardrailsConfig
* @return The threshold to warn when encountering a collection with larger data size than threshold.
*/
@Nullable
DataStorageSpec getCollectionSizeWarnThreshold();
DataStorageSpec.LongBytesBound getCollectionSizeWarnThreshold();
/**
* @return The threshold to prevent collections with larger data size than threshold.
*/
@Nullable
DataStorageSpec getCollectionSizeFailThreshold();
DataStorageSpec.LongBytesBound getCollectionSizeFailThreshold();
/**
* @return The threshold to warn when encountering more elements in a collection than threshold.
@ -272,7 +272,7 @@ public interface GuardrailsConfig
* disabled.
*/
@Nullable
DataStorageSpec getDataDiskUsageMaxDiskSize();
DataStorageSpec.LongBytesBound getDataDiskUsageMaxDiskSize();
/**
* @return The threshold to warn when replication factor is lesser than threshold.

View File

@ -20,7 +20,6 @@ package org.apache.cassandra.db.virtual;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import com.google.common.collect.ImmutableMap;
import org.apache.cassandra.config.Config;

View File

@ -234,7 +234,7 @@ public class ActiveRepairService implements IEndpointStateChangeSubscriber, IFai
.maximumSize(Long.getLong("cassandra.parent_repair_status_cache_size", 100_000))
.build();
DurationSpec duration = getRepairStateExpires();
DurationSpec.LongNanosecondsBound duration = getRepairStateExpires();
int numElements = getRepairStateSize();
logger.info("Storing repair state for {} or for {} elements", duration, numElements);
repairs = CacheBuilder.newBuilder()

View File

@ -3885,7 +3885,7 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
@Override
public void takeSnapshot(String tag, Map<String, String> options, String... entities) throws IOException
{
DurationSpec ttl = options.containsKey("ttl") ? new DurationSpec(options.get("ttl")) : null;
DurationSpec.IntSecondsBound ttl = options.containsKey("ttl") ? new DurationSpec.IntSecondsBound(options.get("ttl")) : null;
if (ttl != null)
{
int minAllowedTtlSecs = CassandraRelevantProperties.SNAPSHOT_MIN_ALLOWED_TTL_SECONDS.getInt();
@ -3988,7 +3988,7 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
* @param skipFlush Skip blocking flush of memtable
* @param keyspaceNames the names of the keyspaces to snapshot; empty means "all."
*/
private void takeSnapshot(String tag, boolean skipFlush, DurationSpec ttl, String... keyspaceNames) throws IOException
private void takeSnapshot(String tag, boolean skipFlush, DurationSpec.IntSecondsBound ttl, String... keyspaceNames) throws IOException
{
if (operationMode == Mode.JOINING)
throw new IOException("Cannot snapshot until bootstrap completes");
@ -4034,7 +4034,7 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
* @param tableList
* list of tables from different keyspace in the form of ks1.cf1 ks2.cf2
*/
private void takeMultipleTableSnapshot(String tag, boolean skipFlush, DurationSpec ttl, String... tableList)
private void takeMultipleTableSnapshot(String tag, boolean skipFlush, DurationSpec.IntSecondsBound ttl, String... tableList)
throws IOException
{
Map<Keyspace, List<String>> keyspaceColumnfamily = new HashMap<Keyspace, List<String>>();
@ -6520,11 +6520,11 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
logger.info("set default keyspace rf to {}", value);
}
private static DataStorageSpec parseDataStorageSpec(String threshold)
private static DataStorageSpec.LongBytesBound parseDataStorageSpec(String threshold)
{
return threshold == null
? null
: new DataStorageSpec(threshold);
: new DataStorageSpec.LongBytesBound(threshold);
}
public int getDefaultKeyspaceReplicationFactor()
@ -6597,7 +6597,7 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
public void setPaxosPurgeGraceSeconds(long v)
{
DatabaseDescriptor.setPaxosPurgeGrace(v, SECONDS);
DatabaseDescriptor.setPaxosPurgeGrace(v);
logger.info("paxos purging grace seconds set to {} via jmx", v);
}

View File

@ -140,7 +140,7 @@ public class DiskUsageMonitor
BigInteger total = used.add(usable);
// That total space can be limited by the config property data_disk_usage_max_disk_size.
DataStorageSpec diskUsageMaxSize = guardrailsConfigSupplier.get().getDataDiskUsageMaxDiskSize();
DataStorageSpec.LongBytesBound diskUsageMaxSize = guardrailsConfigSupplier.get().getDataDiskUsageMaxDiskSize();
if (diskUsageMaxSize != null)
total = total.min(BigInteger.valueOf(diskUsageMaxSize.toBytes()));

View File

@ -54,11 +54,11 @@ public class SnapshotManifest
this.expiresAt = null;
}
public SnapshotManifest(List<String> files, DurationSpec ttl, Instant creationTime)
public SnapshotManifest(List<String> files, DurationSpec.IntSecondsBound ttl, Instant creationTime)
{
this.files = files;
this.createdAt = creationTime;
this.expiresAt = ttl == null ? null : createdAt.plusMillis(ttl.toMilliseconds());
this.expiresAt = ttl == null ? null : createdAt.plusSeconds(ttl.toSeconds());
}
public List<String> getFiles()

View File

@ -253,7 +253,7 @@ public class StreamManager implements StreamManagerMBean
public StreamManager()
{
DurationSpec duration = DatabaseDescriptor.getStreamingStateExpires();
DurationSpec.LongNanosecondsBound duration = DatabaseDescriptor.getStreamingStateExpires();
long sizeBytes = DatabaseDescriptor.getStreamingStateSize().toBytes();
long numElements = sizeBytes / StreamingState.ELEMENT_SIZE;
logger.info("Storing streaming state for {} or for {} elements", duration, numElements);

View File

@ -397,15 +397,26 @@ public class LoaderOptions
errorMsg("Config file not found", options);
}
config = new YamlConfigurationLoader().loadConfig(configFile.toPath().toUri().toURL());
// below 2 checks are needed in order to match the pre-CASSANDRA-15234 upper bound for those parameters which were still in megabits per second
if (config.stream_throughput_outbound.toMegabitsPerSecond() >= Integer.MAX_VALUE)
{
throw new ConfigurationException("Invalid value of stream_throughput_outbound: " + config.stream_throughput_outbound.toString(), false);
}
if (config.inter_dc_stream_throughput_outbound.toMegabitsPerSecond() >= Integer.MAX_VALUE)
{
throw new ConfigurationException("Invalid value of inter_dc_stream_throughput_outbound: " + config.inter_dc_stream_throughput_outbound.toString(), false);
}
}
else
{
config = new Config();
// unthrottle stream by default
config.stream_throughput_outbound = DataRateSpec.inMebibytesPerSecond(0);
config.inter_dc_stream_throughput_outbound = DataRateSpec.inMebibytesPerSecond(0);
config.entire_sstable_stream_throughput_outbound = DataRateSpec.inMebibytesPerSecond(0);
config.entire_sstable_inter_dc_stream_throughput_outbound = DataRateSpec.inMebibytesPerSecond(0);
config.stream_throughput_outbound = new DataRateSpec.IntMebibytesPerSecondBound(0);
config.inter_dc_stream_throughput_outbound = new DataRateSpec.IntMebibytesPerSecondBound(0);
config.entire_sstable_stream_throughput_outbound = new DataRateSpec.IntMebibytesPerSecondBound(0);
config.entire_sstable_inter_dc_stream_throughput_outbound = new DataRateSpec.IntMebibytesPerSecondBound(0);
}
if (cmd.hasOption(STORAGE_PORT_OPTION))

View File

@ -70,7 +70,7 @@ public class Snapshot extends NodeToolCmd
Map<String, String> options = new HashMap<String,String>();
options.put("skipFlush", Boolean.toString(skipFlush));
if (null != ttl) {
DurationSpec d = new DurationSpec(ttl);
DurationSpec.LongNanosecondsBound d = new DurationSpec.LongNanosecondsBound(ttl);
options.put("ttl", d.toString());
}

View File

@ -76,7 +76,7 @@ scripted_user_defined_functions_enabled: true
prepared_statements_cache_size: 1MiB
corrupted_tombstone_strategy: exception
stream_entire_sstables: true
stream_throughput_outbound: 23841823841858MiB/s
stream_throughput_outbound: 23841858MiB/s
sasi_indexes_enabled: true
materialized_views_enabled: true
file_cache_enabled: true

View File

@ -26,6 +26,7 @@ import org.junit.*;
import org.apache.cassandra.config.DataStorageSpec;
import org.apache.cassandra.config.DatabaseDescriptor;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.KIBIBYTES;
import static org.assertj.core.api.Assertions.assertThat;
/**
@ -42,8 +43,8 @@ public class CoordinatorReadSizeWarningTest extends AbstractClientSizeWarning
// setup threshold after init to avoid driver issues loading
// the test uses a rather small limit, which causes driver to fail while loading metadata
CLUSTER.stream().forEach(i -> i.runOnInstance(() -> {
DatabaseDescriptor.setCoordinatorReadSizeWarnThreshold(DataStorageSpec.inKibibytes(1));
DatabaseDescriptor.setCoordinatorReadSizeFailThreshold(DataStorageSpec.inKibibytes(2));
DatabaseDescriptor.setCoordinatorReadSizeWarnThreshold(new DataStorageSpec.LongBytesBound(1, KIBIBYTES));
DatabaseDescriptor.setCoordinatorReadSizeFailThreshold(new DataStorageSpec.LongBytesBound(2, KIBIBYTES));
}));
}

View File

@ -26,6 +26,7 @@ import org.junit.BeforeClass;
import org.apache.cassandra.config.DataStorageSpec;
import org.apache.cassandra.config.DatabaseDescriptor;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.KIBIBYTES;
import static org.assertj.core.api.Assertions.assertThat;
public class LocalReadSizeWarningTest extends AbstractClientSizeWarning
@ -42,8 +43,8 @@ public class LocalReadSizeWarningTest extends AbstractClientSizeWarning
DatabaseDescriptor.setCoordinatorReadSizeWarnThreshold(null);
DatabaseDescriptor.setCoordinatorReadSizeFailThreshold(null);
DatabaseDescriptor.setLocalReadSizeWarnThreshold(DataStorageSpec.inKibibytes(1));
DatabaseDescriptor.setLocalReadSizeFailThreshold(DataStorageSpec.inKibibytes(2));
DatabaseDescriptor.setLocalReadSizeWarnThreshold(new DataStorageSpec.LongBytesBound(1, KIBIBYTES));
DatabaseDescriptor.setLocalReadSizeFailThreshold(new DataStorageSpec.LongBytesBound(2, KIBIBYTES));
}));
}

View File

@ -27,6 +27,7 @@ import org.junit.BeforeClass;
import org.apache.cassandra.config.DataStorageSpec;
import org.apache.cassandra.config.DatabaseDescriptor;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.KIBIBYTES;
import static org.assertj.core.api.Assertions.assertThat;
public class RowIndexSizeWarningTest extends AbstractClientSizeWarning
@ -37,8 +38,8 @@ public class RowIndexSizeWarningTest extends AbstractClientSizeWarning
AbstractClientSizeWarning.setupClass();
CLUSTER.stream().forEach(i -> i.runOnInstance(() -> {
DatabaseDescriptor.setRowIndexReadSizeWarnThreshold(DataStorageSpec.inKibibytes(1));
DatabaseDescriptor.setRowIndexReadSizeFailThreshold(DataStorageSpec.inKibibytes(2));
DatabaseDescriptor.setRowIndexReadSizeWarnThreshold(new DataStorageSpec.LongBytesBound(1, KIBIBYTES));
DatabaseDescriptor.setRowIndexReadSizeFailThreshold(new DataStorageSpec.LongBytesBound(2, KIBIBYTES));
// hack to force multiple index entries
DatabaseDescriptor.setColumnIndexCacheSize(1 << 20);

View File

@ -31,37 +31,57 @@ public class DataRateSpecTest
@Test
public void testConversions()
{
assertEquals(10, new DataRateSpec("10B/s").toBytesPerSecond(), 0);
assertEquals(10240, new DataRateSpec("10KiB/s").toBytesPerSecond(), 0);
assertEquals(0, new DataRateSpec("10KiB/s").toMebibytesPerSecond(), 0.1);
assertEquals(10240, new DataRateSpec("10MiB/s").toKibibytesPerSecond(), 0);
assertEquals(10485760, new DataRateSpec("10MiB/s").toBytesPerSecond(), 0);
assertEquals(10485760, new DataRateSpec("10MiB/s").toBytesPerSecond(), 0);
assertEquals(new DataRateSpec("24MiB/s").toString(), DataRateSpec.megabitsPerSecondInMebibytesPerSecond(200L).toString());
assertEquals(10, new DataRateSpec.LongBytesPerSecondBound("10B/s").toBytesPerSecond(), 0);
assertEquals(10240, new DataRateSpec.LongBytesPerSecondBound("10KiB/s").toBytesPerSecond(), 0);
assertEquals(0, new DataRateSpec.LongBytesPerSecondBound("10KiB/s").toMebibytesPerSecond(), 0.1);
assertEquals(10240, new DataRateSpec.LongBytesPerSecondBound("10MiB/s").toKibibytesPerSecond(), 0);
assertEquals(10485760, new DataRateSpec.LongBytesPerSecondBound("10MiB/s").toBytesPerSecond(), 0);
assertEquals(10485760, new DataRateSpec.LongBytesPerSecondBound("10MiB/s").toBytesPerSecond(), 0);
assertEquals(new DataRateSpec.LongBytesPerSecondBound("24MiB/s").toString(), DataRateSpec.IntMebibytesPerSecondBound.megabitsPerSecondInMebibytesPerSecond(200L).toString());
assertEquals(10, new DataRateSpec.IntMebibytesPerSecondBound("10B/s").toBytesPerSecond(), 0);
assertEquals(10240, new DataRateSpec.IntMebibytesPerSecondBound("10KiB/s").toBytesPerSecond(), 0);
assertEquals(0, new DataRateSpec.IntMebibytesPerSecondBound("10KiB/s").toMebibytesPerSecond(), 0.1);
assertEquals(10240, new DataRateSpec.IntMebibytesPerSecondBound("10MiB/s").toKibibytesPerSecond(), 0);
assertEquals(10485760, new DataRateSpec.IntMebibytesPerSecondBound("10MiB/s").toBytesPerSecond(), 0);
assertEquals(10485760, new DataRateSpec.IntMebibytesPerSecondBound("10MiB/s").toBytesPerSecond(), 0);
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound("24MiB/s").toString(), DataRateSpec.IntMebibytesPerSecondBound.megabitsPerSecondInMebibytesPerSecond(200L).toString());
}
@Test
public void testOverflowingDuringConversion()
{
assertEquals(Long.MAX_VALUE, new DataRateSpec("9223372036854775807B/s").toBytesPerSecond(), 0);
assertEquals(Integer.MAX_VALUE, new DataRateSpec("9223372036854775807B/s").toBytesPerSecondAsInt(), 0);
assertEquals(Long.MAX_VALUE, new DataRateSpec("9223372036854775807KiB/s").toBytesPerSecond(), 0);
assertEquals(Integer.MAX_VALUE, new DataRateSpec("9223372036854775807KiB/s").toBytesPerSecondAsInt(), 0);
assertEquals(Long.MAX_VALUE, new DataRateSpec("9223372036854775807MiB/s").toBytesPerSecond(), 0);
assertEquals(Integer.MAX_VALUE, new DataRateSpec("9223372036854775807MiB/s").toBytesPerSecondAsInt(), 0);
assertEquals(Long.MAX_VALUE, new DataRateSpec("9223372036854775807MiB/s").toBytesPerSecond(), 0);
assertEquals(Integer.MAX_VALUE, new DataRateSpec("9223372036854775807MiB/s").toBytesPerSecondAsInt(), 0);
assertEquals(Integer.MAX_VALUE, new DataRateSpec.IntMebibytesPerSecondBound("2147483649B/s").toBytesPerSecondAsInt(), 0);
assertEquals(Integer.MAX_VALUE, new DataRateSpec.IntMebibytesPerSecondBound(2147483649L / 1024L + "KiB/s").toBytesPerSecondAsInt(), 0);
assertEquals(Integer.MAX_VALUE, new DataRateSpec.IntMebibytesPerSecondBound(2147483649L / 1024L / 1024 + "MiB/s").toBytesPerSecondAsInt(), 0);
assertEquals(Long.MAX_VALUE, new DataRateSpec("9223372036854775807MiB/s").toMegabitsPerSecond(), 0);
assertEquals(Integer.MAX_VALUE, new DataRateSpec("9223372036854775807MiB/s").toMegabitsPerSecondAsInt());
assertEquals(Integer.MAX_VALUE, new DataRateSpec.IntMebibytesPerSecondBound(2147483646L + "MiB/s").toMegabitsPerSecondAsInt());
assertEquals(Integer.MAX_VALUE, new DataRateSpec.IntMebibytesPerSecondBound(2147483647L + "KiB/s").toKibibytesPerSecondAsInt());
assertEquals(Integer.MAX_VALUE, new DataRateSpec.IntMebibytesPerSecondBound(2147483649L / 1024L + "MiB/s").toKibibytesPerSecondAsInt());
assertEquals(Integer.MAX_VALUE-1, new DataRateSpec.IntMebibytesPerSecondBound(2147483646L + "MiB/s").toMebibytesPerSecondAsInt());
assertThatThrownBy(() -> new DataRateSpec.IntMebibytesPerSecondBound("2147483648MiB/s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: 2147483648MiB/s. " +
"It shouldn't be more than 2147483646 in mebibytes_per_second");
assertThatThrownBy(() -> new DataRateSpec.IntMebibytesPerSecondBound(2147483648L)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: 2.147483648E9 mebibytes_per_second. " +
"It shouldn't be more than 2147483646 in mebibytes_per_second");
assertThatThrownBy(() -> new DataRateSpec.IntMebibytesPerSecondBound((Integer.MAX_VALUE * 1024L + 1L) + "KiB/s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: 2199023254529KiB/s. " +
"It shouldn't be more than 2147483646 in mebibytes_per_second");
assertThatThrownBy(() -> new DataRateSpec.IntMebibytesPerSecondBound((Integer.MAX_VALUE * 1024L * 1024 + 1L) + "B/s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: 2251799812636673B/s. " +
"It shouldn't be more than 2147483646 in mebibytes_per_second");
assertThatThrownBy(() -> DataRateSpec.IntMebibytesPerSecondBound.megabitsPerSecondInMebibytesPerSecond(2147483648L)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: 2147483648 megabits per second; " +
"stream_throughput_outbound and " +
"inter_dc_stream_throughput_outbound should " +
"be between 0 and 2147483647 in megabits per second");
assertEquals(Long.MAX_VALUE, new DataRateSpec("9223372036854775807KiB/s").toKibibytesPerSecond(), 0);
assertEquals(Integer.MAX_VALUE, new DataRateSpec("9223372036854775807KiB/s").toKibibytesPerSecondAsInt());
assertEquals(Long.MAX_VALUE, new DataRateSpec("9223372036854775807MiB/s").toKibibytesPerSecond(), 0);
assertEquals(Integer.MAX_VALUE, new DataRateSpec("9223372036854775807MiB/s").toKibibytesPerSecondAsInt());
assertEquals(Long.MAX_VALUE, new DataRateSpec("9223372036854775807MiB/s").toMebibytesPerSecond(), 0);
assertEquals(Integer.MAX_VALUE, new DataRateSpec("9223372036854775807MiB/s").toMebibytesPerSecondAsInt());
}
@Test
@ -78,38 +98,97 @@ public class DataRateSpecTest
@Test
public void testInvalidInputs()
{
assertThatThrownBy(() -> new DataRateSpec("10")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid bit rate: 10");
assertThatThrownBy(() -> new DataRateSpec("-10b/s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid bit rate: -10b/s");
assertThatThrownBy(() -> new DataRateSpec("10xb/s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid bit rate: 10xb/s");
assertThatThrownBy(() -> new DataRateSpec("9223372036854775809B/s")
assertThatThrownBy(() -> new DataRateSpec.LongBytesPerSecondBound("10")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: 10");
assertThatThrownBy(() -> new DataRateSpec.LongBytesPerSecondBound("-10b/s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: -10b/s");
assertThatThrownBy(() -> new DataRateSpec.LongBytesPerSecondBound(-10, DataRateSpec.DataRateUnit.BYTES_PER_SECOND)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: value must be non-negative");
assertThatThrownBy(() -> new DataRateSpec.LongBytesPerSecondBound("10xb/s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: 10xb/s");
assertThatThrownBy(() -> new DataRateSpec.LongBytesPerSecondBound("9223372036854775809B/s")
.toBytesPerSecond()).isInstanceOf(NumberFormatException.class)
.hasMessageContaining("For input string: \"9223372036854775809\"");
assertThatThrownBy(() -> new DataRateSpec.LongBytesPerSecondBound("9223372036854775809KiB/s")
.toBytesPerSecond()).isInstanceOf(NumberFormatException.class)
.hasMessageContaining("For input string: \"9223372036854775809\"");
assertThatThrownBy(() -> new DataRateSpec.LongBytesPerSecondBound("9223372036854775809MiB/s")
.toBytesPerSecond()).isInstanceOf(NumberFormatException.class)
.hasMessageContaining("For input string: \"9223372036854775809\"");
assertThatThrownBy(() -> new DataRateSpec.IntMebibytesPerSecondBound("2147483648MiB/s")
.toBytesPerSecond()).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: 2147483648MiB/s. It shouldn't be more" +
" than 2147483646 in mebibytes_per_second");
}
@Test
public void testInvalidForConversion()
{
//just test the cast to Int as currently we don't even have any long bound rates and there is a very low probability of ever having them
assertEquals(Integer.MAX_VALUE, new DataRateSpec.LongBytesPerSecondBound("92233720368547758B/s").toBytesPerSecondAsInt());
assertThatThrownBy(() -> new DataRateSpec.LongBytesPerSecondBound(Long.MAX_VALUE + "B/s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: 9223372036854775807B/s. " +
"It shouldn't be more than 9223372036854775806 in bytes_per_second");
assertThatThrownBy(() -> new DataRateSpec.LongBytesPerSecondBound(Long.MAX_VALUE + "MiB/s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: 9223372036854775807MiB/s. " +
"It shouldn't be more than 9223372036854775806 in bytes_per_second");
assertThatThrownBy(() -> new DataRateSpec.LongBytesPerSecondBound(Long.MAX_VALUE - 5 + "KiB/s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data rate: 9223372036854775802KiB/s. " +
"It shouldn't be more than 9223372036854775806 in bytes_per_second");
}
@Test
public void testValidUnits()
{
// we need toString as internally it is double and they are not 0.0 equal but for the end user the double numbers don't exist
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound("24MiB/s").toString(), DataRateSpec.IntMebibytesPerSecondBound.megabitsPerSecondInMebibytesPerSecond(200).toString());
}
@SuppressWarnings("AssertBetweenInconvertibleTypes")
@Test
public void testEquals()
{
assertEquals(new DataRateSpec("10B/s"), new DataRateSpec("10B/s"));
assertEquals(new DataRateSpec("10KiB/s"), new DataRateSpec("10240B/s"));
assertEquals(new DataRateSpec("10240B/s"), new DataRateSpec("10KiB/s"));
assertEquals(DataRateSpec.inMebibytesPerSecond(Long.MAX_VALUE), DataRateSpec.inMebibytesPerSecond(Long.MAX_VALUE));
assertNotEquals(DataRateSpec.inMebibytesPerSecond(Long.MAX_VALUE), DataRateSpec.inBytesPerSecond(Long.MAX_VALUE));
assertNotEquals(new DataRateSpec("0KiB/s"), new DataRateSpec("10MiB/s"));
assertEquals(new DataRateSpec.LongBytesPerSecondBound("10B/s"), new DataRateSpec.LongBytesPerSecondBound("10B/s"));
assertEquals(new DataRateSpec.LongBytesPerSecondBound("10KiB/s"), new DataRateSpec.LongBytesPerSecondBound("10240B/s"));
assertEquals(new DataRateSpec.LongBytesPerSecondBound("10240B/s"), new DataRateSpec.LongBytesPerSecondBound("10KiB/s"));
assertNotEquals(new DataRateSpec.LongBytesPerSecondBound("0KiB/s"), new DataRateSpec.LongBytesPerSecondBound("10MiB/s"));
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound("10B/s"), new DataRateSpec.IntMebibytesPerSecondBound("10B/s"));
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound("10KiB/s"), new DataRateSpec.IntMebibytesPerSecondBound("10240B/s"));
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound("10240B/s"), new DataRateSpec.IntMebibytesPerSecondBound("10KiB/s"));
assertNotEquals(new DataRateSpec.IntMebibytesPerSecondBound("0KiB/s"), new DataRateSpec.IntMebibytesPerSecondBound("10MiB/s"));
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound("10B/s"), new DataRateSpec.LongBytesPerSecondBound("10B/s"));
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound("10KiB/s"), new DataRateSpec.LongBytesPerSecondBound("10240B/s"));
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound("10240B/s"), new DataRateSpec.LongBytesPerSecondBound("10KiB/s"));
assertNotEquals(new DataRateSpec.IntMebibytesPerSecondBound("0KiB/s"), new DataRateSpec.LongBytesPerSecondBound("10MiB/s"));
}
@Test
public void thereAndBack()
public void thereAndBackLongBytesPerSecondBound()
{
Gen<DataRateSpec.DataRateUnit> unitGen = SourceDSL.arbitrary().enumValues(DataRateSpec.DataRateUnit.class);
Gen<Long> valueGen = SourceDSL.longs().between(0, Long.MAX_VALUE);
// DataRateSpec is a special case where we have double so we can accomodate the backward compatibility for parameters which were in
// megabits per second before without losing precision
// Extremely big numbers might be not completely accurate, that is why here Long.MAX_VALUE is not failing for bytes being >= Long.MAX_VALUE
Gen<Long> valueGen = SourceDSL.longs().between(0, Long.MAX_VALUE/1024L/1024L); // the biggest value in MiB/s that won't lead to B/s overflow
qt().forAll(valueGen, unitGen).check((value, unit) -> {
DataRateSpec there = new DataRateSpec(value, unit);
DataRateSpec back = new DataRateSpec(there.toString());
DataRateSpec BACK = new DataRateSpec(there.toString());
return there.equals(back) && there.equals(BACK);
DataRateSpec.LongBytesPerSecondBound there = new DataRateSpec.LongBytesPerSecondBound(value, unit);
DataRateSpec.LongBytesPerSecondBound back = new DataRateSpec.LongBytesPerSecondBound(there.toString());
return there.equals(back) && back.equals(there);
});
}
@Test
public void thereAndBackIntMebibytesPerSecondBound()
{
Gen<DataRateSpec.DataRateUnit> unitGen = SourceDSL.arbitrary().enumValues(DataRateSpec.DataRateUnit.class);
Gen<Long> valueGen = SourceDSL.longs().between(0, Integer.MAX_VALUE-1); // max MiB/s
qt().forAll(valueGen, unitGen).check((value, unit) -> {
DataRateSpec.IntMebibytesPerSecondBound there = new DataRateSpec.IntMebibytesPerSecondBound(value, unit);
DataRateSpec.IntMebibytesPerSecondBound back = new DataRateSpec.IntMebibytesPerSecondBound(there.toString());
return there.equals(back) && back.equals(there);
});
}
@ -128,8 +207,8 @@ public class DataRateSpecTest
private static Gen<DataRateSpec> gen()
{
Gen<DataRateSpec.DataRateUnit> unitGen = SourceDSL.arbitrary().enumValues(DataRateSpec.DataRateUnit.class);
Gen<Long> valueGen = SourceDSL.longs().between(0, Long.MAX_VALUE);
Gen<DataRateSpec> gen = rs -> new DataRateSpec(valueGen.generate(rs), unitGen.generate(rs));
Gen<Long> valueGen = SourceDSL.longs().between(0, Long.MAX_VALUE/1024L/1024/1024);
Gen<DataRateSpec> gen = rs -> new DataRateSpec.LongBytesPerSecondBound(valueGen.generate(rs), unitGen.generate(rs));
return gen.describedAs(DataRateSpec::toString);
}
}
}

View File

@ -24,54 +24,138 @@ import org.junit.Test;
import org.quicktheories.core.Gen;
import org.quicktheories.generators.SourceDSL;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.BYTES;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.GIBIBYTES;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.KIBIBYTES;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.MEBIBYTES;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.*;
import static org.quicktheories.QuickTheory.qt;
public class DataStorageSpecTest
{
private static final long MAX_LONG_CONFIG_VALUE = Long.MAX_VALUE - 1;
@Test
public void testConversions()
{
assertEquals(10, new DataStorageSpec("10B").toBytes());
assertEquals(10240, new DataStorageSpec("10KiB").toBytes());
assertEquals(0, new DataStorageSpec("10KiB").toMebibytes());
assertEquals(10240, new DataStorageSpec("10MiB").toKibibytes());
assertEquals(10485760, new DataStorageSpec("10MiB").toBytes());
assertEquals(10, new DataStorageSpec.LongBytesBound("10B").toBytes());
assertEquals(10240, new DataStorageSpec.LongBytesBound("10KiB").toBytes());
assertEquals(10485760, new DataStorageSpec.LongBytesBound("10MiB").toBytes());
assertEquals(1073741824, new DataStorageSpec.LongBytesBound("1GiB").toBytes());
assertEquals(1024, new DataStorageSpec.LongMebibytesBound("1GiB").toMebibytes());
assertEquals(10485760, new DataStorageSpec.LongMebibytesBound("10MiB").toBytes());
assertEquals(10240, new DataStorageSpec.LongMebibytesBound("10MiB").toKibibytes());
assertEquals(1024 * 1024 * 1024, new DataStorageSpec.IntBytesBound("1GiB").toBytes());
assertEquals(10240, new DataStorageSpec.IntKibibytesBound("10MiB").toKibibytes());
assertEquals(1024, new DataStorageSpec.IntMebibytesBound("1GiB").toMebibytes());
assertEquals(10, new DataStorageSpec.LongBytesBound(10, BYTES).toBytes());
assertEquals(10240, new DataStorageSpec.LongBytesBound(10, KIBIBYTES).toBytes());
assertEquals(10485760, new DataStorageSpec.LongBytesBound(10, MEBIBYTES).toBytes());
assertEquals(1073741824, new DataStorageSpec.LongBytesBound(1, GIBIBYTES).toBytes());
assertEquals(1024, new DataStorageSpec.LongMebibytesBound(1, GIBIBYTES).toMebibytes());
assertEquals(1024 * 1024, new DataStorageSpec.LongMebibytesBound(1, GIBIBYTES).toKibibytes());
assertEquals(10485760, new DataStorageSpec.LongMebibytesBound(10, MEBIBYTES).toBytes());
assertEquals(10240, new DataStorageSpec.IntKibibytesBound(10, MEBIBYTES).toKibibytes());
assertEquals(1024, new DataStorageSpec.IntMebibytesBound(1, GIBIBYTES).toMebibytes());
}
@Test
public void testOverflowingDuringConversion()
public void testOverflowingConversion()
{
assertEquals(Long.MAX_VALUE, new DataStorageSpec("9223372036854775807B").toBytes());
assertEquals(Integer.MAX_VALUE, new DataStorageSpec("9223372036854775807B").toBytesAsInt());
assertEquals(Long.MAX_VALUE, new DataStorageSpec("9223372036854775807KiB").toBytes());
assertEquals(Integer.MAX_VALUE, new DataStorageSpec("9223372036854775807KiB").toBytesAsInt());
assertEquals(Long.MAX_VALUE, new DataStorageSpec("9223372036854775807MiB").toBytes());
assertEquals(Integer.MAX_VALUE, new DataStorageSpec("9223372036854775807MiB").toBytesAsInt());
assertEquals(Long.MAX_VALUE, new DataStorageSpec("9223372036854775807GiB").toBytes());
assertEquals(Integer.MAX_VALUE, new DataStorageSpec("9223372036854775807GiB").toBytesAsInt());
assertThatThrownBy(() -> new DataStorageSpec.IntBytesBound("2147483648B")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 2147483648B. " +
"It shouldn't be more than 2147483646 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.IntBytesBound(2147483648L)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 2147483648 bytes. " +
"It shouldn't be more than 2147483646 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.IntBytesBound("2147483648KiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 2147483648KiB. " +
"It shouldn't be more than 2147483646 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.IntBytesBound("35791395MiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 35791395MiB. " +
"It shouldn't be more than 2147483646 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.IntBytesBound("34954GiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 34954GiB. " +
"It shouldn't be more than 2147483646 in bytes");
assertEquals(Long.MAX_VALUE, new DataStorageSpec("9223372036854775807KiB").toKibibytes());
assertEquals(Integer.MAX_VALUE, new DataStorageSpec("9223372036854775807KiB").toKibibytesAsInt());
assertEquals(Long.MAX_VALUE, new DataStorageSpec("9223372036854775807MiB").toKibibytes());
assertEquals(Integer.MAX_VALUE, new DataStorageSpec("9223372036854775807MiB").toKibibytesAsInt());
assertEquals(Long.MAX_VALUE, new DataStorageSpec("9223372036854775807GiB").toKibibytes());
assertEquals(Integer.MAX_VALUE, new DataStorageSpec("9223372036854775807GiB").toKibibytesAsInt());
assertThatThrownBy(() -> new DataStorageSpec.IntKibibytesBound("2147483648B")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 2147483648B " +
"Accepted units:[KIBIBYTES, MEBIBYTES, GIBIBYTES]");
assertThatThrownBy(() -> new DataStorageSpec.IntKibibytesBound(2147483648L, BYTES)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 2147483648B " +
"Accepted units:[KIBIBYTES, MEBIBYTES, GIBIBYTES]");
assertThatThrownBy(() -> new DataStorageSpec.IntKibibytesBound("2147483648KiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 2147483648KiB. " +
"It shouldn't be more than 2147483646 in kibibytes");
assertThatThrownBy(() -> new DataStorageSpec.IntKibibytesBound("35791395MiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 35791395MiB. " +
"It shouldn't be more than 2147483646 in kibibytes");
assertThatThrownBy(() -> new DataStorageSpec.IntKibibytesBound("34954GiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 34954GiB. " +
"It shouldn't be more than 2147483646 in kibibytes");
assertEquals(Long.MAX_VALUE, new DataStorageSpec("9223372036854775807MiB").toMebibytes());
assertEquals(Integer.MAX_VALUE, new DataStorageSpec("9223372036854775807MiB").toMebibytesAsInt());
assertEquals(Long.MAX_VALUE, new DataStorageSpec("9223372036854775807GiB").toMebibytes());
assertEquals(Integer.MAX_VALUE, new DataStorageSpec("9223372036854775807GiB").toMebibytesAsInt());
assertThatThrownBy(() -> new DataStorageSpec.IntMebibytesBound("2147483648B")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 2147483648B " +
"Accepted units:[MEBIBYTES, GIBIBYTES]");
assertThatThrownBy(() -> new DataStorageSpec.IntMebibytesBound("2147483648MiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 2147483648MiB. " +
"It shouldn't be more than 2147483646 in mebibytes");
assertThatThrownBy(() -> new DataStorageSpec.IntMebibytesBound(2147483648L, MEBIBYTES)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 2147483648 mebibytes. " +
"It shouldn't be more than 2147483646 in mebibytes");
assertThatThrownBy(() -> new DataStorageSpec.IntMebibytesBound("2097152GiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 2097152GiB. " +
"It shouldn't be more than 2147483646 in mebibytes");
assertThatThrownBy(() -> new DataStorageSpec.IntMebibytesBound(2147483648L)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 2147483648 mebibytes." +
" It shouldn't be more than 2147483646 in mebibytes");
assertEquals(Long.MAX_VALUE, new DataStorageSpec("9223372036854775807GiB").toGibibytes());
assertEquals(Integer.MAX_VALUE, new DataStorageSpec("9223372036854775807GiB").toGibibytesAsInt());
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound(Long.MAX_VALUE + "B")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775807B. " +
"It shouldn't be more than 9223372036854775806 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound(Long.MAX_VALUE, BYTES)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775807 bytes. " +
"It shouldn't be more than 9223372036854775806 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound(Long.MAX_VALUE)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775807 bytes. " +
"It shouldn't be more than 9223372036854775806 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound(Long.MAX_VALUE + "KiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775807KiB. " +
"It shouldn't be more than 9223372036854775806 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound("9223372036854775MiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775MiB. " +
"It shouldn't be more than 9223372036854775806 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound("9223372036854775GiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775GiB. " +
"It shouldn't be more than 9223372036854775806 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.LongMebibytesBound(Long.MAX_VALUE + "B")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775807B " +
"Accepted units:[MEBIBYTES, GIBIBYTES]");
assertThatThrownBy(() -> new DataStorageSpec.LongMebibytesBound(Long.MAX_VALUE, BYTES)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775807B " +
"Accepted units:[MEBIBYTES, GIBIBYTES]");
assertThatThrownBy(() -> new DataStorageSpec.LongMebibytesBound(Long.MAX_VALUE + "KiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775807KiB " +
"Accepted units:[MEBIBYTES, GIBIBYTES]");
assertThatThrownBy(() -> new DataStorageSpec.LongMebibytesBound(Long.MAX_VALUE + "MiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775807MiB. " +
"It shouldn't be more than 9223372036854775806 in mebibytes");
assertThatThrownBy(() -> new DataStorageSpec.LongMebibytesBound("9223372036854775555GiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775555GiB. " +
"It shouldn't be more than 9223372036854775806 in mebibytes");
assertThatThrownBy(() -> new DataStorageSpec.LongMebibytesBound(Long.MAX_VALUE)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775807 mebibytes." +
" It shouldn't be more than 9223372036854775806 in mebibytes");
}
@Test
public void testFromSymbol()
{
assertEquals(DataStorageSpec.DataStorageUnit.fromSymbol("B"), DataStorageSpec.DataStorageUnit.BYTES);
assertEquals(DataStorageSpec.DataStorageUnit.fromSymbol("B"), BYTES);
assertEquals(DataStorageSpec.DataStorageUnit.fromSymbol("KiB"), DataStorageSpec.DataStorageUnit.KIBIBYTES);
assertEquals(DataStorageSpec.DataStorageUnit.fromSymbol("MiB"), DataStorageSpec.DataStorageUnit.MEBIBYTES);
assertEquals(DataStorageSpec.DataStorageUnit.fromSymbol("GiB"), DataStorageSpec.DataStorageUnit.GIBIBYTES);
@ -83,62 +167,82 @@ public class DataStorageSpecTest
@Test
public void testInvalidInputs()
{
assertThatThrownBy(() -> new DataStorageSpec("10")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 10");
assertThatThrownBy(() -> new DataStorageSpec("-10bps")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: -10bps");
assertThatThrownBy(() -> new DataStorageSpec("-10b")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: -10b");
assertThatThrownBy(() -> new DataStorageSpec("10HG")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 10HG");
assertThatThrownBy(() -> new DataStorageSpec("9223372036854775809B")
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound("10")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 10");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound("-10bps")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: -10bps");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound("-10b")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: -10b");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound(-10, BYTES)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: value must be non-negative");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound("10HG")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 10HG");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound("9223372036854775809B")
.toBytes()).isInstanceOf(NumberFormatException.class)
.hasMessageContaining("For input string: \"9223372036854775809\"");
assertThatThrownBy(() -> new DataStorageSpec.IntKibibytesBound("10B")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 10B Accepted units");
assertThatThrownBy(() -> new DataStorageSpec.IntMebibytesBound("10B")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 10B Accepted units");
assertThatThrownBy(() -> new DataStorageSpec.LongMebibytesBound("10B")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 10B Accepted units");
}
@Test
public void testValidUnits()
{
assertEquals(10240L, new DataStorageSpec.IntBytesBound("10KiB").toBytes());
assertEquals(10L, new DataStorageSpec.IntKibibytesBound("10KiB").toKibibytes());
assertEquals(10L, new DataStorageSpec.IntMebibytesBound("10MiB").toMebibytes());
}
@Test
public void testInvalidForConversion()
{
//just test the cast to Int
// assertEquals(Integer.MAX_VALUE, new DataStorageSpec.LongBytesBound("9223372036854775806B").toBytesAsInt());
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound(Long.MAX_VALUE + "B")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775807B. " +
"It shouldn't be more than 9223372036854775806 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound(Long.MAX_VALUE + "KiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775807KiB. " +
"It shouldn't be more than 9223372036854775806 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound(Long.MAX_VALUE-5L + "MiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775802MiB. " +
"It shouldn't be more than 9223372036854775806 in bytes");
assertThatThrownBy(() -> new DataStorageSpec.LongBytesBound(Long.MAX_VALUE-5L + "GiB")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 9223372036854775802GiB. " +
"It shouldn't be more than 9223372036854775806 in bytes");
}
@Test
public void testEquals()
{
assertEquals(new DataStorageSpec("10B"), new DataStorageSpec("10B"));
assertEquals(new DataStorageSpec.LongBytesBound("10B"), new DataStorageSpec.LongBytesBound("10B"));
assertEquals(new DataStorageSpec("10KiB"), new DataStorageSpec("10240B"));
assertEquals(new DataStorageSpec("10240B"), new DataStorageSpec("10KiB"));
assertEquals(new DataStorageSpec.LongBytesBound.LongBytesBound("10KiB"), new DataStorageSpec.LongBytesBound.LongBytesBound("10240B"));
assertEquals(new DataStorageSpec.LongBytesBound.LongBytesBound("10240B"), new DataStorageSpec.LongBytesBound("10KiB"));
assertEquals(new DataStorageSpec("10MiB"), new DataStorageSpec("10240KiB"));
assertEquals(new DataStorageSpec("10240KiB"), new DataStorageSpec("10MiB"));
assertEquals(new DataStorageSpec.LongBytesBound("10MiB"), new DataStorageSpec.LongBytesBound("10240KiB"));
assertEquals(new DataStorageSpec.LongBytesBound("10240KiB"), new DataStorageSpec.LongBytesBound("10MiB"));
assertEquals(new DataStorageSpec("10GiB"), new DataStorageSpec("10240MiB"));
assertEquals(new DataStorageSpec("10240MiB"), new DataStorageSpec("10GiB"));
assertEquals(new DataStorageSpec.LongBytesBound("10GiB"), new DataStorageSpec.LongBytesBound("10240MiB"));
assertEquals(new DataStorageSpec.LongBytesBound("10240MiB"), new DataStorageSpec.LongBytesBound("10GiB"));
assertNotEquals(DataStorageSpec.inBytes(Long.MAX_VALUE), DataStorageSpec.inGibibytes(Long.MAX_VALUE));
assertNotEquals(DataStorageSpec.inBytes(Long.MAX_VALUE), DataStorageSpec.inMebibytes(Long.MAX_VALUE));
assertNotEquals(DataStorageSpec.inBytes(Long.MAX_VALUE), DataStorageSpec.inKibibytes(Long.MAX_VALUE));
assertEquals(DataStorageSpec.inBytes(Long.MAX_VALUE), DataStorageSpec.inBytes(Long.MAX_VALUE));
assertEquals(new DataStorageSpec.LongBytesBound(MAX_LONG_CONFIG_VALUE, BYTES), new DataStorageSpec.LongBytesBound(MAX_LONG_CONFIG_VALUE, BYTES));
assertNotEquals(DataStorageSpec.inKibibytes(Long.MAX_VALUE), DataStorageSpec.inGibibytes(Long.MAX_VALUE));
assertNotEquals(DataStorageSpec.inKibibytes(Long.MAX_VALUE), DataStorageSpec.inMebibytes(Long.MAX_VALUE));
assertEquals(DataStorageSpec.inKibibytes(Long.MAX_VALUE), DataStorageSpec.inKibibytes(Long.MAX_VALUE));
assertNotEquals(DataStorageSpec.inKibibytes(Long.MAX_VALUE), DataStorageSpec.inBytes(Long.MAX_VALUE));
assertNotEquals(DataStorageSpec.inMebibytes(Long.MAX_VALUE), DataStorageSpec.inGibibytes(Long.MAX_VALUE));
assertEquals(DataStorageSpec.inMebibytes(Long.MAX_VALUE), DataStorageSpec.inMebibytes(Long.MAX_VALUE));
assertNotEquals(DataStorageSpec.inMebibytes(Long.MAX_VALUE), DataStorageSpec.inBytes(Long.MAX_VALUE));
assertNotEquals(DataStorageSpec.inMebibytes(Long.MAX_VALUE), DataStorageSpec.inBytes(Long.MAX_VALUE));
assertEquals(DataStorageSpec.inGibibytes(Long.MAX_VALUE), DataStorageSpec.inGibibytes(Long.MAX_VALUE));
assertNotEquals(DataStorageSpec.inGibibytes(Long.MAX_VALUE), DataStorageSpec.inMebibytes(Long.MAX_VALUE));
assertNotEquals(DataStorageSpec.inGibibytes(Long.MAX_VALUE), DataStorageSpec.inKibibytes(Long.MAX_VALUE));
assertNotEquals(DataStorageSpec.inGibibytes(Long.MAX_VALUE), DataStorageSpec.inBytes(Long.MAX_VALUE));
assertNotEquals(new DataStorageSpec("0MiB"), new DataStorageSpec("10KiB"));
assertNotEquals(new DataStorageSpec.LongBytesBound("0MiB"), new DataStorageSpec.LongBytesBound("10KiB"));
}
@Test
public void thereAndBack()
public void thereAndBackLongBytesBound()
{
qt().forAll(gen()).check(there -> {
DataStorageSpec back = new DataStorageSpec(there.toString());
DataStorageSpec BACK = new DataStorageSpec(there.toString().toUpperCase(Locale.ROOT).replace("I", "i"));
DataStorageSpec.LongBytesBound back = new DataStorageSpec.LongBytesBound(there.toString());
DataStorageSpec.LongBytesBound BACK = new DataStorageSpec.LongBytesBound(there.toString().toUpperCase(Locale.ROOT).replace("I", "i"));
return there.equals(back) && there.equals(BACK);
});
}
@ -155,11 +259,11 @@ public class DataStorageSpecTest
qt().forAll(gen(), gen()).check((a, b) -> !a.equals(b) || a.hashCode() == b.hashCode());
}
private static Gen<DataStorageSpec> gen()
private static Gen<DataStorageSpec.LongBytesBound> gen()
{
Gen<DataStorageSpec.DataStorageUnit> unitGen = SourceDSL.arbitrary().enumValues(DataStorageSpec.DataStorageUnit.class);
Gen<Long> valueGen = SourceDSL.longs().between(0, Long.MAX_VALUE);
Gen<DataStorageSpec> gen = rs -> new DataStorageSpec(valueGen.generate(rs), unitGen.generate(rs));
return gen.describedAs(DataStorageSpec::toString);
Gen<DataStorageSpec.LongBytesBound.DataStorageUnit> unitGen = SourceDSL.arbitrary().enumValues(DataStorageSpec.LongBytesBound.DataStorageUnit.class);
Gen<Long> valueGen = SourceDSL.longs().between(0, Long.MAX_VALUE/1024L/1024/1024); // max in GiB we can have without overflowing
Gen<DataStorageSpec.LongBytesBound> gen = rs -> new DataStorageSpec.LongBytesBound(valueGen.generate(rs), unitGen.generate(rs));
return gen.describedAs(DataStorageSpec.LongBytesBound::toString);
}
}

View File

@ -89,26 +89,47 @@ public class DatabaseDescriptorRefTest
"org.apache.cassandra.config.Config$UserFunctionTimeoutPolicy",
"org.apache.cassandra.config.Config$CorruptedTombstoneStrategy",
"org.apache.cassandra.config.DatabaseDescriptor$ByteUnit",
"org.apache.cassandra.config.ParameterizedClass",
"org.apache.cassandra.config.DataRateSpec",
"org.apache.cassandra.config.DataRateSpec$DataRateUnit",
"org.apache.cassandra.config.DataRateSpec$DataRateUnit$1",
"org.apache.cassandra.config.DataRateSpec$DataRateUnit$2",
"org.apache.cassandra.config.DataRateSpec$DataRateUnit$3",
"org.apache.cassandra.config.DataStorageSpec",
"org.apache.cassandra.config.DataStorageSpec$DataStorageUnit",
"org.apache.cassandra.config.DataStorageSpec$DataStorageUnit$1",
"org.apache.cassandra.config.DataStorageSpec$DataStorageUnit$2",
"org.apache.cassandra.config.DataStorageSpec$DataStorageUnit$3",
"org.apache.cassandra.config.DataStorageSpec$DataStorageUnit$4",
"org.apache.cassandra.config.DataStorageSpec$IntBytesBound",
"org.apache.cassandra.config.DataStorageSpec$IntKibibytesBound",
"org.apache.cassandra.config.DataStorageSpec$IntMebibytesBound",
"org.apache.cassandra.config.DataStorageSpec$LongBytesBound",
"org.apache.cassandra.config.DataStorageSpec$LongMebibytesBound",
"org.apache.cassandra.config.DurationSpec",
"org.apache.cassandra.config.DataRateSpec$IntMebibytesPerSecondBound",
"org.apache.cassandra.config.DurationSpec$LongMillisecondsBound",
"org.apache.cassandra.config.DurationSpec$LongNanosecondsBound",
"org.apache.cassandra.config.DurationSpec$LongSecondsBound",
"org.apache.cassandra.config.DurationSpec$IntMillisecondsBound",
"org.apache.cassandra.config.DurationSpec$IntSecondsBound",
"org.apache.cassandra.config.DurationSpec$IntMinutesBound",
"org.apache.cassandra.config.EncryptionOptions",
"org.apache.cassandra.config.EncryptionOptions$ClientEncryptionOptions",
"org.apache.cassandra.config.EncryptionOptions$ServerEncryptionOptions",
"org.apache.cassandra.config.EncryptionOptions$ServerEncryptionOptions$InternodeEncryption",
"org.apache.cassandra.config.EncryptionOptions$ServerEncryptionOptions$OutgoingEncryptedPortSource",
"org.apache.cassandra.db.guardrails.GuardrailsConfig",
"org.apache.cassandra.db.guardrails.GuardrailsConfigMBean",
"org.apache.cassandra.db.guardrails.GuardrailsConfig$ConsistencyLevels",
"org.apache.cassandra.db.guardrails.GuardrailsConfig$TableProperties",
"org.apache.cassandra.config.GuardrailsOptions",
"org.apache.cassandra.config.GuardrailsOptions$Config",
"org.apache.cassandra.config.GuardrailsOptions$ConsistencyLevels",
"org.apache.cassandra.config.GuardrailsOptions$TableProperties",
"org.apache.cassandra.config.ParameterizedClass",
"org.apache.cassandra.config.ReplicaFilteringProtectionOptions",
"org.apache.cassandra.config.YamlConfigurationLoader",
"org.apache.cassandra.config.YamlConfigurationLoader$PropertiesChecker",
"org.apache.cassandra.config.YamlConfigurationLoader$PropertiesChecker$1",
"org.apache.cassandra.config.YamlConfigurationLoader$CustomConstructor",
"org.apache.cassandra.config.TransparentDataEncryptionOptions",
"org.apache.cassandra.config.StartupChecksOptions",
"org.apache.cassandra.config.SubnetGroups",
"org.apache.cassandra.config.TrackWarnings",
"org.apache.cassandra.db.ConsistencyLevel",
@ -119,6 +140,10 @@ public class DatabaseDescriptorRefTest
"org.apache.cassandra.db.commitlog.CommitLogSegmentManagerStandard",
"org.apache.cassandra.db.commitlog.CommitLog",
"org.apache.cassandra.db.commitlog.CommitLogMBean",
"org.apache.cassandra.db.guardrails.GuardrailsConfig",
"org.apache.cassandra.db.guardrails.GuardrailsConfigMBean",
"org.apache.cassandra.db.guardrails.GuardrailsConfig$ConsistencyLevels",
"org.apache.cassandra.db.guardrails.GuardrailsConfig$TableProperties",
"org.apache.cassandra.db.guardrails.Values$Config",
"org.apache.cassandra.dht.IPartitioner",
"org.apache.cassandra.distributed.api.IInstance",
@ -198,25 +223,7 @@ public class DatabaseDescriptorRefTest
"org.apache.cassandra.ConsoleAppenderCustomizer",
"org.apache.cassandra.locator.InetAddressAndPort",
"org.apache.cassandra.cql3.statements.schema.AlterKeyspaceStatement",
"org.apache.cassandra.cql3.statements.schema.CreateKeyspaceStatement",
"org.apache.cassandra.config.DurationSpec",
"org.apache.cassandra.config.DataStorageSpec",
"org.apache.cassandra.config.DataStorageSpec$DataStorageUnit",
"org.apache.cassandra.config.DataStorageSpec$DataStorageUnit$1",
"org.apache.cassandra.config.DataStorageSpec$DataStorageUnit$2",
"org.apache.cassandra.config.DataStorageSpec$DataStorageUnit$3",
"org.apache.cassandra.config.DataStorageSpec$DataStorageUnit$4",
"org.apache.cassandra.config.DataRateSpec",
"org.apache.cassandra.config.DataRateSpec$DataRateUnit",
"org.apache.cassandra.config.DataRateSpec$DataRateUnit$1",
"org.apache.cassandra.config.DataRateSpec$DataRateUnit$2",
"org.apache.cassandra.config.DataRateSpec$DataRateUnit$3",
"org.apache.cassandra.config.SmallestDurationMinutes",
"org.apache.cassandra.config.SmallestDurationSeconds",
"org.apache.cassandra.config.SmallestDurationMilliseconds",
"org.apache.cassandra.config.SmallestDataStorageKibibytes",
"org.apache.cassandra.config.SmallestDataStorageMebibytes",
"org.apache.cassandra.config.StartupChecksOptions",
"org.apache.cassandra.cql3.statements.schema.CreateKeyspaceStatement"
};
static final Set<String> checkedClasses = new HashSet<>(Arrays.asList(validClasses));

View File

@ -37,6 +37,7 @@ import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.assertj.core.api.Assertions;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.KIBIBYTES;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
@ -333,8 +334,7 @@ public class DatabaseDescriptorTest
{
Config testConfig = new Config();
SmallestDurationMilliseconds greaterThanLowestTimeout = SmallestDurationMilliseconds
.inMilliseconds(DatabaseDescriptor.LOWEST_ACCEPTED_TIMEOUT.toMilliseconds() + 1);
DurationSpec.LongMillisecondsBound greaterThanLowestTimeout = new DurationSpec.LongMillisecondsBound(DatabaseDescriptor.LOWEST_ACCEPTED_TIMEOUT.toMilliseconds() + 1);
testConfig.read_request_timeout = greaterThanLowestTimeout;
testConfig.range_request_timeout = greaterThanLowestTimeout;
@ -353,7 +353,7 @@ public class DatabaseDescriptorTest
assertEquals(testConfig.request_timeout, greaterThanLowestTimeout);
//set less than Lowest acceptable value
SmallestDurationMilliseconds lowerThanLowestTimeout = SmallestDurationMilliseconds.inMilliseconds(DatabaseDescriptor.LOWEST_ACCEPTED_TIMEOUT.toMilliseconds() - 1);
DurationSpec.LongMillisecondsBound lowerThanLowestTimeout = new DurationSpec.LongMillisecondsBound(DatabaseDescriptor.LOWEST_ACCEPTED_TIMEOUT.toMilliseconds() - 1);
testConfig.read_request_timeout = lowerThanLowestTimeout;
testConfig.range_request_timeout = lowerThanLowestTimeout;
@ -625,8 +625,8 @@ public class DatabaseDescriptorTest
public void testClientLargeReadWarnGreaterThanAbort()
{
Config conf = new Config();
conf.coordinator_read_size_warn_threshold = DataStorageSpec.inKibibytes(2);
conf.coordinator_read_size_fail_threshold = DataStorageSpec.inKibibytes(1);
conf.coordinator_read_size_warn_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
conf.coordinator_read_size_fail_threshold = new DataStorageSpec.LongBytesBound(1, KIBIBYTES);
Assertions.assertThatThrownBy(() -> DatabaseDescriptor.applyReadThresholdsValidations(conf))
.isInstanceOf(ConfigurationException.class)
.hasMessage("coordinator_read_size_fail_threshold (1KiB) must be greater than or equal to coordinator_read_size_warn_threshold (2KiB)");
@ -636,8 +636,8 @@ public class DatabaseDescriptorTest
public void testClientLargeReadWarnEqAbort()
{
Config conf = new Config();
conf.coordinator_read_size_warn_threshold = DataStorageSpec.inKibibytes(2);
conf.coordinator_read_size_fail_threshold = DataStorageSpec.inKibibytes(2);
conf.coordinator_read_size_warn_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
conf.coordinator_read_size_fail_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
DatabaseDescriptor.applyReadThresholdsValidations(conf);
}
@ -645,7 +645,7 @@ public class DatabaseDescriptorTest
public void testClientLargeReadWarnEnabledAbortDisabled()
{
Config conf = new Config();
conf.coordinator_read_size_warn_threshold = DataStorageSpec.inKibibytes(2);
conf.coordinator_read_size_warn_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
conf.coordinator_read_size_fail_threshold = null;
DatabaseDescriptor.applyReadThresholdsValidations(conf);
}
@ -654,8 +654,8 @@ public class DatabaseDescriptorTest
public void testClientLargeReadAbortEnabledWarnDisabled()
{
Config conf = new Config();
conf.coordinator_read_size_warn_threshold = DataStorageSpec.inKibibytes(0);
conf.coordinator_read_size_fail_threshold = DataStorageSpec.inKibibytes(2);
conf.coordinator_read_size_warn_threshold = new DataStorageSpec.LongBytesBound(0, KIBIBYTES);
conf.coordinator_read_size_fail_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
DatabaseDescriptor.applyReadThresholdsValidations(conf);
}
@ -665,8 +665,8 @@ public class DatabaseDescriptorTest
public void testLocalLargeReadWarnGreaterThanAbort()
{
Config conf = new Config();
conf.local_read_size_warn_threshold = DataStorageSpec.inKibibytes(2);
conf.local_read_size_fail_threshold = DataStorageSpec.inKibibytes(1);
conf.local_read_size_warn_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
conf.local_read_size_fail_threshold = new DataStorageSpec.LongBytesBound(1, KIBIBYTES);
Assertions.assertThatThrownBy(() -> DatabaseDescriptor.applyReadThresholdsValidations(conf))
.isInstanceOf(ConfigurationException.class)
.hasMessage("local_read_size_fail_threshold (1KiB) must be greater than or equal to local_read_size_warn_threshold (2KiB)");
@ -676,8 +676,8 @@ public class DatabaseDescriptorTest
public void testLocalLargeReadWarnEqAbort()
{
Config conf = new Config();
conf.local_read_size_warn_threshold = DataStorageSpec.inKibibytes(2);
conf.local_read_size_fail_threshold = DataStorageSpec.inKibibytes(2);
conf.local_read_size_warn_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
conf.local_read_size_fail_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
DatabaseDescriptor.applyReadThresholdsValidations(conf);
}
@ -685,7 +685,7 @@ public class DatabaseDescriptorTest
public void testLocalLargeReadWarnEnabledAbortDisabled()
{
Config conf = new Config();
conf.local_read_size_warn_threshold = DataStorageSpec.inKibibytes(2);
conf.local_read_size_warn_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
conf.local_read_size_fail_threshold = null;
DatabaseDescriptor.applyReadThresholdsValidations(conf);
}
@ -694,8 +694,8 @@ public class DatabaseDescriptorTest
public void testLocalLargeReadAbortEnabledWarnDisabled()
{
Config conf = new Config();
conf.local_read_size_warn_threshold = DataStorageSpec.inKibibytes(0);
conf.local_read_size_fail_threshold = DataStorageSpec.inKibibytes(2);
conf.local_read_size_warn_threshold = new DataStorageSpec.LongBytesBound(0, KIBIBYTES);
conf.local_read_size_fail_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
DatabaseDescriptor.applyReadThresholdsValidations(conf);
}
@ -705,8 +705,8 @@ public class DatabaseDescriptorTest
public void testRowIndexSizeWarnGreaterThanAbort()
{
Config conf = new Config();
conf.row_index_read_size_warn_threshold = DataStorageSpec.inKibibytes(2);
conf.row_index_read_size_fail_threshold = DataStorageSpec.inKibibytes(1);
conf.row_index_read_size_warn_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
conf.row_index_read_size_fail_threshold = new DataStorageSpec.LongBytesBound(1, KIBIBYTES);
Assertions.assertThatThrownBy(() -> DatabaseDescriptor.applyReadThresholdsValidations(conf))
.isInstanceOf(ConfigurationException.class)
.hasMessage("row_index_read_size_fail_threshold (1KiB) must be greater than or equal to row_index_read_size_warn_threshold (2KiB)");
@ -716,8 +716,8 @@ public class DatabaseDescriptorTest
public void testRowIndexSizeWarnEqAbort()
{
Config conf = new Config();
conf.row_index_read_size_warn_threshold = DataStorageSpec.inKibibytes(2);
conf.row_index_read_size_fail_threshold = DataStorageSpec.inKibibytes(2);
conf.row_index_read_size_warn_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
conf.row_index_read_size_fail_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
DatabaseDescriptor.applyReadThresholdsValidations(conf);
}
@ -725,7 +725,7 @@ public class DatabaseDescriptorTest
public void testRowIndexSizeWarnEnabledAbortDisabled()
{
Config conf = new Config();
conf.row_index_read_size_warn_threshold = DataStorageSpec.inKibibytes(2);
conf.row_index_read_size_warn_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
conf.row_index_read_size_fail_threshold = null;
DatabaseDescriptor.applyReadThresholdsValidations(conf);
}
@ -734,8 +734,8 @@ public class DatabaseDescriptorTest
public void testRowIndexSizeAbortEnabledWarnDisabled()
{
Config conf = new Config();
conf.row_index_read_size_warn_threshold = DataStorageSpec.inKibibytes(0);
conf.row_index_read_size_fail_threshold = DataStorageSpec.inKibibytes(2);
conf.row_index_read_size_warn_threshold = new DataStorageSpec.LongBytesBound(0, KIBIBYTES);
conf.row_index_read_size_fail_threshold = new DataStorageSpec.LongBytesBound(2, KIBIBYTES);
DatabaseDescriptor.applyReadThresholdsValidations(conf);
}

View File

@ -24,28 +24,31 @@ import org.junit.Test;
import org.quicktheories.core.Gen;
import org.quicktheories.generators.SourceDSL;
import static java.util.concurrent.TimeUnit.MICROSECONDS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.*;
import static org.quicktheories.QuickTheory.qt;
public class DurationSpecTest
{
private static final long MAX_INT_CONFIG_VALUE = Integer.MAX_VALUE - 1;
@SuppressWarnings("AssertBetweenInconvertibleTypes")
@Test
public void testConversions()
{
assertEquals(10L, new DurationSpec("10s").toSeconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807s").toSecondsAsInt());
assertEquals(10000, new DurationSpec("10s").toMilliseconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807s").toMillisecondsAsInt());
assertEquals(0, new DurationSpec("10s").toMinutes());
assertEquals(10, new DurationSpec("10m").toMinutes());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807s").toMinutesAsInt());
assertEquals(600000, new DurationSpec("10m").toMilliseconds());
assertEquals(600, new DurationSpec("10m").toSeconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807s").toSecondsAsInt());
assertEquals(DurationSpec.inDoubleMilliseconds(0.7), new DurationSpec("1ms"));
assertEquals(DurationSpec.inDoubleMilliseconds(0.33), new DurationSpec("0ms"));
assertEquals(DurationSpec.inDoubleMilliseconds(0.333), new DurationSpec("0ms"));
assertEquals(10000000000L, new DurationSpec.LongNanosecondsBound ("10s").toNanoseconds());
assertEquals(MAX_INT_CONFIG_VALUE, new DurationSpec.IntSecondsBound(MAX_INT_CONFIG_VALUE + "s").toSeconds());
assertEquals(MAX_INT_CONFIG_VALUE, new DurationSpec.LongMillisecondsBound(MAX_INT_CONFIG_VALUE + "ms").toMilliseconds());
assertEquals(600000000000L, new DurationSpec.LongNanosecondsBound ("10m").toNanoseconds());
assertEquals(MAX_INT_CONFIG_VALUE, new DurationSpec.IntMinutesBound(MAX_INT_CONFIG_VALUE + "m").toMinutes());
assertEquals(MAX_INT_CONFIG_VALUE, new DurationSpec.IntSecondsBound(MAX_INT_CONFIG_VALUE + "s").toSeconds());
assertEquals(new DurationSpec.IntMillisecondsBound(0.7, TimeUnit.MILLISECONDS), new DurationSpec.LongNanosecondsBound("1ms"));
assertEquals(new DurationSpec.IntMillisecondsBound(0.33, TimeUnit.MILLISECONDS), new DurationSpec.LongNanosecondsBound("0ms"));
assertEquals(new DurationSpec.IntMillisecondsBound(0.333, TimeUnit.MILLISECONDS), new DurationSpec.LongNanosecondsBound("0ms"));
}
@Test
@ -58,102 +61,259 @@ public class DurationSpecTest
assertEquals(DurationSpec.fromSymbol("s"), TimeUnit.SECONDS);
assertEquals(DurationSpec.fromSymbol("us"), TimeUnit.MICROSECONDS);
assertEquals(DurationSpec.fromSymbol("µs"), TimeUnit.MICROSECONDS);
assertEquals(DurationSpec.fromSymbol("ns"), TimeUnit.NANOSECONDS);
assertThatThrownBy(() -> DurationSpec.fromSymbol("n")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Unsupported time unit: n");
assertEquals(DurationSpec.fromSymbol("ns"), NANOSECONDS);
assertThatThrownBy(() -> DurationSpec.fromSymbol("n")).isInstanceOf(IllegalArgumentException.class);
}
@Test
public void testGetSymbol()
{
assertEquals(DurationSpec.getSymbol(TimeUnit.MILLISECONDS), "ms");
assertEquals(DurationSpec.getSymbol(TimeUnit.DAYS), "d");
assertEquals(DurationSpec.getSymbol(TimeUnit.HOURS), "h");
assertEquals(DurationSpec.getSymbol(TimeUnit.MINUTES), "m");
assertEquals(DurationSpec.getSymbol(TimeUnit.SECONDS), "s");
assertEquals(DurationSpec.getSymbol(TimeUnit.MICROSECONDS), "us");
assertEquals(DurationSpec.getSymbol(TimeUnit.NANOSECONDS), "ns");
assertEquals(DurationSpec.symbol(TimeUnit.MILLISECONDS), "ms");
assertEquals(DurationSpec.symbol(TimeUnit.DAYS), "d");
assertEquals(DurationSpec.symbol(TimeUnit.HOURS), "h");
assertEquals(DurationSpec.symbol(TimeUnit.MINUTES), "m");
assertEquals(DurationSpec.symbol(TimeUnit.SECONDS), "s");
assertEquals(DurationSpec.symbol(TimeUnit.MICROSECONDS), "us");
assertEquals(DurationSpec.symbol(NANOSECONDS), "ns");
}
@Test
public void testInvalidInputs()
{
assertThatThrownBy(() -> new DurationSpec("10")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10");
assertThatThrownBy(() -> new DurationSpec("-10s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: -10s");
assertThatThrownBy(() -> new DurationSpec("10xd")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10xd");
assertThatThrownBy(() -> new DurationSpec("0.333555555ms")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 0.333555555ms");
assertThatThrownBy(() -> new DurationSpec.LongNanosecondsBound("10")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10");
assertThatThrownBy(() -> new DurationSpec.LongNanosecondsBound("-10s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: -10s");
assertThatThrownBy(() -> new DurationSpec.LongNanosecondsBound(-10, SECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: value must be non-negativ");
assertThatThrownBy(() -> new DurationSpec.LongNanosecondsBound("10xd")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10xd");
assertThatThrownBy(() -> new DurationSpec.LongNanosecondsBound("0.333555555ms")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 0.333555555ms");
}
@Test
public void testInvalidForConversion()
{
assertThatThrownBy(() -> new DurationSpec.LongNanosecondsBound(Long.MAX_VALUE + "ns")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 9223372036854775807ns. " +
"It shouldn't be more than 9223372036854775806 in nanoseconds");
assertThatThrownBy(() -> new DurationSpec.LongNanosecondsBound(Long.MAX_VALUE + "ms")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 9223372036854775807ms. " +
"It shouldn't be more than 9223372036854775806 in nanoseconds");
assertThatThrownBy(() -> new DurationSpec.LongNanosecondsBound(Long.MAX_VALUE-5 + "µs")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 9223372036854775802µs. " +
"It shouldn't be more than 9223372036854775806 in nanoseconds");
assertThatThrownBy(() -> new DurationSpec.LongNanosecondsBound(Long.MAX_VALUE-5 + "us")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 9223372036854775802us. " +
"It shouldn't be more than 9223372036854775806 in nanoseconds");
assertThatThrownBy(() -> new DurationSpec.LongNanosecondsBound(Long.MAX_VALUE-5 + "s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 9223372036854775802s. " +
"It shouldn't be more than 9223372036854775806 in nanoseconds");
assertThatThrownBy(() -> new DurationSpec.LongNanosecondsBound(Long.MAX_VALUE-5 + "h")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 9223372036854775802h. " +
"It shouldn't be more than 9223372036854775806 in nanoseconds");
assertThatThrownBy(() -> new DurationSpec.LongNanosecondsBound(Long.MAX_VALUE-5 + "d")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 9223372036854775802d. " +
"It shouldn't be more than 9223372036854775806 in nanoseconds");
}
@Test
public void testOverflowingConversion()
{
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound("2147483648ms")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 2147483648ms." +
" It shouldn't be more than 2147483646 in milliseconds");
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound(2147483648L)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 2147483648 milliseconds. " +
"It shouldn't be more than 2147483646 in milliseconds");
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound("2147483648s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 2147483648s. " +
"It shouldn't be more than 2147483646 in milliseconds");
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound("35791395m")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 35791395m. " +
"It shouldn't be more than 2147483646 in milliseconds");
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound("597h")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 597h. " +
"It shouldn't be more than 2147483646 in milliseconds");
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound("24856d")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 24856d. " +
"It shouldn't be more than 2147483646 in milliseconds");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound("2147483648s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 2147483648s. " +
"It shouldn't be more than 2147483646 in seconds");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound(2147483648L)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 2147483648 seconds. " +
"It shouldn't be more than 2147483646 in seconds");
assertThatThrownBy(() -> DurationSpec.IntSecondsBound.inSecondsString("2147483648")).isInstanceOf(NumberFormatException.class)
.hasMessageContaining("For input string: \"2147483648\"");
assertThatThrownBy(() -> DurationSpec.IntSecondsBound.inSecondsString("2147483648s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 2147483648s. " +
"It shouldn't be more than 2147483646 in seconds");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound("35791395m")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 35791395m. " +
"It shouldn't be more than 2147483646 in seconds");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound("596524h")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 596524h. " +
"It shouldn't be more than 2147483646 in seconds");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound("24856d")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 24856d. " +
"It shouldn't be more than 2147483646 in seconds");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound("2147483648s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 2147483648s " +
"Accepted units:[MINUTES, HOURS, DAYS]");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound("2147483648m")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 2147483648m. " +
"It shouldn't be more than 2147483646 in minutes");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound("35791395h")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 35791395h. " +
"It shouldn't be more than 2147483646 in minutes");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound("1491309d")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 1491309d. " +
"It shouldn't be more than 2147483646 in minutes");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound(2147483648L)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 2147483648 minutes. " +
"It shouldn't be more than 2147483646 in minutes");
}
@SuppressWarnings("AssertBetweenInconvertibleTypes")
@Test
public void testEquals()
{
assertEquals(new DurationSpec("10s"), new DurationSpec("10s"));
assertEquals(new DurationSpec("10s"), new DurationSpec("10000ms"));
assertEquals(new DurationSpec("10000ms"), new DurationSpec("10s"));
assertEquals(DurationSpec.inMinutes(Long.MAX_VALUE), DurationSpec.inMinutes(Long.MAX_VALUE));
assertEquals(new DurationSpec("4h"), new DurationSpec("14400s"));
assertEquals(DurationSpec.inSecondsString("14400"), new DurationSpec("14400s"));
assertEquals(DurationSpec.inSecondsString("4h"), new DurationSpec("14400s"));
assertEquals(DurationSpec.inSecondsString("14400s"), new DurationSpec("14400s"));
assertEquals(DurationSpec.inHours(Long.MAX_VALUE),DurationSpec.inHours(Long.MAX_VALUE));
assertNotEquals(DurationSpec.inMinutes(Long.MAX_VALUE), DurationSpec.inMilliseconds(Long.MAX_VALUE));
assertNotEquals(new DurationSpec("0m"), new DurationSpec("10ms"));
assertEquals(new DurationSpec.LongNanosecondsBound ("10s"), new DurationSpec.LongNanosecondsBound ("10s"));
assertEquals(new DurationSpec.LongNanosecondsBound ("10s"), new DurationSpec.LongNanosecondsBound ("10000ms"));
assertEquals(new DurationSpec.LongNanosecondsBound ("10000ms"), new DurationSpec.LongNanosecondsBound ("10s"));
assertEquals(new DurationSpec.LongNanosecondsBound ("4h"), new DurationSpec.LongNanosecondsBound ("14400s"));
assertEquals(DurationSpec.LongNanosecondsBound .IntSecondsBound.inSecondsString("14400"), new DurationSpec.LongNanosecondsBound ("14400s"));
assertEquals(DurationSpec.LongNanosecondsBound .IntSecondsBound.inSecondsString("4h"), new DurationSpec.LongNanosecondsBound ("14400s"));
assertEquals(DurationSpec.LongNanosecondsBound .IntSecondsBound.inSecondsString("14400s"), new DurationSpec.LongNanosecondsBound ("14400s"));
assertNotEquals(new DurationSpec.LongNanosecondsBound ("0m"), new DurationSpec.LongNanosecondsBound ("10ms"));
assertEquals(Long.MAX_VALUE-1, new DurationSpec.LongNanosecondsBound ("9223372036854775806ns").toNanoseconds());
}
@Test
public void thereAndBack()
{
Gen<TimeUnit> unitGen = SourceDSL.arbitrary().enumValues(TimeUnit.class);
Gen<Long> valueGen = SourceDSL.longs().between(0, Long.MAX_VALUE);
Gen<Long> valueGen = SourceDSL.longs().between(0, Long.MAX_VALUE/24/60/60/1000L/1000L/1000L);
qt().forAll(valueGen, unitGen).check((value, unit) -> {
DurationSpec there = new DurationSpec(value, unit);
DurationSpec back = new DurationSpec(there.toString());
DurationSpec.LongNanosecondsBound there = new DurationSpec.LongNanosecondsBound (value, unit);
DurationSpec.LongNanosecondsBound back = new DurationSpec.LongNanosecondsBound (there.toString());
return there.equals(back);
});
}
@Test
public void testOverflowingDuringConversion()
public void testValidUnits()
{
// we are heavily dependent on the Java TimeUnit for our configuration of type duration. We want to be sure
// that any regression in handlining overflow will be caught quickly on our end
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807ns").toNanoseconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807ns").toNanosecondsAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807ms").toNanoseconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807ms").toNanosecondsAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807s").toNanoseconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807s").toNanosecondsAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807m").toNanoseconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807m").toNanosecondsAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807h").toNanoseconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807h").toNanosecondsAsInt());
assertEquals(10L, new DurationSpec.IntMillisecondsBound("10ms").toMilliseconds());
assertEquals(10L, new DurationSpec.IntSecondsBound("10s").toSeconds());
assertEquals(new DurationSpec.IntSecondsBound("10s"), DurationSpec.IntSecondsBound.inSecondsString("10"));
assertEquals(new DurationSpec.IntSecondsBound("10s"), DurationSpec.IntSecondsBound.inSecondsString("10s"));
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807ms").toMilliseconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807ms").toMillisecondsAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807s").toMilliseconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807s").toMillisecondsAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807m").toMilliseconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807m").toMillisecondsAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807h").toMilliseconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807h").toMillisecondsAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807s").toSeconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807s").toSecondsAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807m").toSeconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807m").toSecondsAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807h").toSeconds());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807h").toSecondsAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807m").toMinutes());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807m").toMinutesAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807h").toMinutes());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807h").toMinutesAsInt());
assertEquals(Long.MAX_VALUE, new DurationSpec("9223372036854775807h").toHours());
assertEquals(Integer.MAX_VALUE, new DurationSpec("9223372036854775807h").toHoursAsInt());
assertEquals(10L, new DurationSpec.LongMillisecondsBound("10ms").toMilliseconds());
assertEquals(10L, new DurationSpec.LongSecondsBound("10s").toSeconds());
}
}
@Test
public void testInvalidUnits()
{
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound("10ns")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ns " +
"Accepted units:[MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS]");
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound(10, NANOSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 NANOSECONDS " +
"Accepted units:[MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS]");
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound("10us")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10us " +
"Accepted units:[MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS]");
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound(10, MICROSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MICROSECONDS " +
"Accepted units:[MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS]");
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound("10µs")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10µs " +
"Accepted units:[MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS]");
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound(10, MICROSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MICROSECONDS " +
"Accepted units:[MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS]");
assertThatThrownBy(() -> new DurationSpec.IntMillisecondsBound("-10s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: -10s " +
"Accepted units:[MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS]");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound("10ms")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ms Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound(10, MILLISECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MILLISECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound("10ns")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ns Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound(10, NANOSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 NANOSECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound("10us")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10us Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound(10, MICROSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MICROSECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound("10µs")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10µs Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound(10, MICROSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MICROSECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntSecondsBound("-10s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: -10s");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound("10s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10s Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound(10, SECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 SECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound("10ms")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ms Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound(10, MILLISECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MILLISECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound("10ns")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ns Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound(10, NANOSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 NANOSECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound("10us")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10us Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound(10, MICROSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MICROSECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound("10µs")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10µs Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound(10, MICROSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MICROSECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.IntMinutesBound("-10s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: -10s");
assertThatThrownBy(() -> new DurationSpec.LongMillisecondsBound("10ns")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ns Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongMillisecondsBound(10, NANOSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 NANOSECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongMillisecondsBound("10us")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10us Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongMillisecondsBound(10, MICROSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MICROSECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongMillisecondsBound("10µs")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10µs Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongMillisecondsBound(10, MICROSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MICROSECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongMillisecondsBound("-10s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: -10s");
assertThatThrownBy(() -> new DurationSpec.LongSecondsBound("10ms")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ms Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongSecondsBound(10, MILLISECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MILLISECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongSecondsBound("10ns")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ns Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongSecondsBound(10, NANOSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 NANOSECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongSecondsBound(10, MICROSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MICROSECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongSecondsBound("10µs")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10µs Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongSecondsBound(10, MICROSECONDS)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10 MICROSECONDS Accepted units");
assertThatThrownBy(() -> new DurationSpec.LongSecondsBound("-10s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: -10s");
}
}

View File

@ -18,6 +18,8 @@
package org.apache.cassandra.config;
import java.util.concurrent.TimeUnit;
import org.junit.BeforeClass;
import org.junit.Test;
@ -41,66 +43,66 @@ public class LoadOldYAMLBackwardCompatibilityTest
{
Config config = DatabaseDescriptor.loadConfig();
assertEquals(DurationSpec.inMilliseconds(10800000), config.max_hint_window);
assertEquals(DurationSpec.inHours(3), config.max_hint_window);
assertEquals(DurationSpec.inMilliseconds(0), config.native_transport_idle_timeout);
assertEquals(DurationSpec.inMilliseconds(10000), config.request_timeout);
assertEquals(DurationSpec.inMilliseconds(5000), config.read_request_timeout);
assertEquals(DurationSpec.inMilliseconds(10000), config.range_request_timeout);
assertEquals(DurationSpec.inMilliseconds(2000), config.write_request_timeout);
assertEquals(DurationSpec.inMilliseconds(5000), config.counter_write_request_timeout);
assertEquals(DurationSpec.inMilliseconds(1800), config.cas_contention_timeout);
assertEquals(DurationSpec.inMilliseconds(60000), config.truncate_request_timeout);
assertEquals(DurationSpec.inSeconds(300), config.streaming_keep_alive_period);
assertEquals(DurationSpec.inMilliseconds(500), config.slow_query_log_timeout);
assertEquals(new DurationSpec.IntMillisecondsBound(10800000), config.max_hint_window);
assertEquals(new DurationSpec.IntMillisecondsBound("3h"), config.max_hint_window);
assertEquals(new DurationSpec.LongMillisecondsBound(0), config.native_transport_idle_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(10000), config.request_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(5000), config.read_request_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(10000), config.range_request_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(2000), config.write_request_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(5000), config.counter_write_request_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(1800), config.cas_contention_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(60000), config.truncate_request_timeout);
assertEquals(new DurationSpec.IntSecondsBound(300), config.streaming_keep_alive_period);
assertEquals(new DurationSpec.LongMillisecondsBound(500), config.slow_query_log_timeout);
assertNull(config.memtable_heap_space);
assertNull(config.memtable_offheap_space);
assertNull( config.repair_session_space);
assertEquals(DataStorageSpec.inBytes(4194304), config.internode_application_send_queue_capacity);
assertEquals(DataStorageSpec.inBytes(134217728), config.internode_application_send_queue_reserve_endpoint_capacity);
assertEquals(DataStorageSpec.inBytes(536870912), config.internode_application_send_queue_reserve_global_capacity);
assertEquals(DataStorageSpec.inBytes(4194304), config.internode_application_receive_queue_capacity);
assertEquals(DataStorageSpec.inBytes(134217728), config.internode_application_receive_queue_reserve_endpoint_capacity);
assertEquals(DataStorageSpec.inBytes(536870912), config.internode_application_receive_queue_reserve_global_capacity);
assertEquals(DurationSpec.inMilliseconds(2000), config.internode_tcp_connect_timeout);
assertEquals(DurationSpec.inMilliseconds(30000), config.internode_tcp_user_timeout);
assertEquals(DurationSpec.inMilliseconds(300000), config.internode_streaming_tcp_user_timeout);
assertEquals(DataStorageSpec.inMebibytes(16), config.native_transport_max_frame_size);
assertEquals(DataStorageSpec.inMebibytes(256), config.max_value_size);
assertEquals(DataStorageSpec.inKibibytes(4), config.column_index_size);
assertEquals(DataStorageSpec.inKibibytes(2), config.column_index_cache_size);
assertEquals(DataStorageSpec.inKibibytes(5), config.batch_size_warn_threshold);
assertEquals(DataRateSpec.inMebibytesPerSecond(64), config.compaction_throughput);
assertEquals(DataStorageSpec.inMebibytes(50), config.min_free_space_per_drive);
assertEquals(DataRateSpec.inMebibytesPerSecond(23841858).toString(), config.stream_throughput_outbound.toString());
assertEquals(DataRateSpec.megabitsPerSecondInMebibytesPerSecond(200000000).toString(), config.stream_throughput_outbound.toString());
assertEquals(DataRateSpec.inMebibytesPerSecond(24), config.inter_dc_stream_throughput_outbound);
assertEquals(new DataStorageSpec.IntBytesBound(4194304), config.internode_application_send_queue_capacity);
assertEquals(new DataStorageSpec.IntBytesBound(134217728), config.internode_application_send_queue_reserve_endpoint_capacity);
assertEquals(new DataStorageSpec.IntBytesBound(536870912), config.internode_application_send_queue_reserve_global_capacity);
assertEquals(new DataStorageSpec.IntBytesBound(4194304), config.internode_application_receive_queue_capacity);
assertEquals(new DataStorageSpec.IntBytesBound(134217728), config.internode_application_receive_queue_reserve_endpoint_capacity);
assertEquals(new DataStorageSpec.IntBytesBound(536870912), config.internode_application_receive_queue_reserve_global_capacity);
assertEquals(new DurationSpec.IntMillisecondsBound(2000), config.internode_tcp_connect_timeout);
assertEquals(new DurationSpec.IntMillisecondsBound(30000), config.internode_tcp_user_timeout);
assertEquals(new DurationSpec.IntMillisecondsBound(300000), config.internode_streaming_tcp_user_timeout);
assertEquals(new DataStorageSpec.IntMebibytesBound(16), config.native_transport_max_frame_size);
assertEquals(new DataStorageSpec.IntMebibytesBound(256), config.max_value_size);
assertEquals(new DataStorageSpec.IntKibibytesBound(4), config.column_index_size);
assertEquals(new DataStorageSpec.IntKibibytesBound(2), config.column_index_cache_size);
assertEquals(new DataStorageSpec.IntKibibytesBound(5), config.batch_size_warn_threshold);
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound(64), config.compaction_throughput);
assertEquals(new DataStorageSpec.IntMebibytesBound(50), config.min_free_space_per_drive);
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound(23841858).toString(), config.stream_throughput_outbound.toString());
assertEquals(DataRateSpec.IntMebibytesPerSecondBound.megabitsPerSecondInMebibytesPerSecond(200000000).toString(), config.stream_throughput_outbound.toString());
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound(24), config.inter_dc_stream_throughput_outbound);
assertNull(config.commitlog_total_space);
assertEquals(DurationSpec.inDoubleMilliseconds(0), config.commitlog_sync_group_window);
assertEquals(DurationSpec.inMilliseconds(0), config.commitlog_sync_period);
assertEquals(DataStorageSpec.inMebibytes(5), config.commitlog_segment_size);
assertEquals(new DurationSpec.IntMillisecondsBound(0.0, TimeUnit.MILLISECONDS), config.commitlog_sync_group_window);
assertEquals(new DurationSpec.IntMillisecondsBound(0), config.commitlog_sync_period);
assertEquals(new DataStorageSpec.IntMebibytesBound(5), config.commitlog_segment_size);
assertNull(config.periodic_commitlog_sync_lag_block); //Integer
assertNull(config.max_mutation_size);
assertEquals(DataStorageSpec.inMebibytes(0), config.cdc_total_space);
assertEquals(DurationSpec.inMilliseconds(250), config.cdc_free_space_check_interval);
assertEquals(DurationSpec.inMilliseconds(100), config.dynamic_snitch_update_interval);
assertEquals(DurationSpec.inMilliseconds(600000), config.dynamic_snitch_reset_interval);
assertEquals(DataStorageSpec.inKibibytes(1024), config.hinted_handoff_throttle);
assertEquals(DataStorageSpec.inKibibytes(1024), config.batchlog_replay_throttle);
assertEquals(DurationSpec.inMilliseconds(10000), config.hints_flush_period);
assertEquals(DataStorageSpec.inMebibytes(128), config.max_hints_file_size);
assertEquals(DataStorageSpec.inKibibytes(10240), config.trickle_fsync_interval);
assertEquals(DataStorageSpec.inMebibytes(50), config.sstable_preemptive_open_interval);
assertEquals(new DataStorageSpec.IntMebibytesBound(0), config.cdc_total_space);
assertEquals(new DurationSpec.IntMillisecondsBound(250), config.cdc_free_space_check_interval);
assertEquals(new DurationSpec.IntMillisecondsBound(100), config.dynamic_snitch_update_interval);
assertEquals(new DurationSpec.IntMillisecondsBound(600000), config.dynamic_snitch_reset_interval);
assertEquals(new DataStorageSpec.IntKibibytesBound(1024), config.hinted_handoff_throttle);
assertEquals(new DataStorageSpec.IntKibibytesBound(1024), config.batchlog_replay_throttle);
assertEquals(new DurationSpec.IntMillisecondsBound(10000), config.hints_flush_period);
assertEquals(new DataStorageSpec.IntMebibytesBound(128), config.max_hints_file_size);
assertEquals(new DataStorageSpec.IntKibibytesBound(10240), config.trickle_fsync_interval);
assertEquals(new DataStorageSpec.IntMebibytesBound(50), config.sstable_preemptive_open_interval);
assertNull( config.key_cache_size);
assertEquals(DataStorageSpec.inMebibytes(16), config.row_cache_size);
assertEquals(new DataStorageSpec.LongMebibytesBound(16), config.row_cache_size);
assertNull(config.counter_cache_size);
assertNull(config.networking_cache_size);
assertNull(config.file_cache_size);
assertNull(config.index_summary_capacity);
assertEquals(DurationSpec.inMilliseconds(200), config.gc_log_threshold);
assertEquals(DurationSpec.inMilliseconds(1000), config.gc_warn_threshold);
assertEquals(DurationSpec.inSeconds(86400), config.trace_type_query_ttl);
assertEquals(DurationSpec.inSeconds(604800), config.trace_type_repair_ttl);
assertEquals(new DurationSpec.IntMillisecondsBound(200), config.gc_log_threshold);
assertEquals(new DurationSpec.IntMillisecondsBound(1000), config.gc_warn_threshold);
assertEquals(new DurationSpec.IntSecondsBound(86400), config.trace_type_query_ttl);
assertEquals(new DurationSpec.IntSecondsBound(604800), config.trace_type_repair_ttl);
assertNull(config.prepared_statements_cache_size);
assertTrue(config.user_defined_functions_enabled);
assertTrue(config.scripted_user_defined_functions_enabled);
@ -109,21 +111,21 @@ public class LoadOldYAMLBackwardCompatibilityTest
assertTrue(config.sasi_indexes_enabled);
assertTrue(config.drop_compact_storage_enabled);
assertTrue(config.user_defined_functions_threads_enabled);
assertEquals(DurationSpec.inMilliseconds(2000), config.permissions_validity);
assertEquals(new DurationSpec.IntMillisecondsBound(2000), config.permissions_validity);
assertNull(config.permissions_update_interval);
assertEquals(DurationSpec.inMilliseconds(2000), config.roles_validity);
assertEquals(new DurationSpec.IntMillisecondsBound(2000), config.roles_validity);
assertNull(config.roles_update_interval);
assertEquals(DurationSpec.inMilliseconds(2000), config.credentials_validity);
assertEquals(new DurationSpec.IntMillisecondsBound(2000), config.credentials_validity);
assertNull(config.credentials_update_interval);
assertEquals(DurationSpec.inMinutes(60), config.index_summary_resize_interval);
assertEquals(new DurationSpec.IntMinutesBound(60), config.index_summary_resize_interval);
//parameters which names have not changed with CASSANDRA-15234
assertEquals(DurationSpec.inSecondsString("14400"), config.key_cache_save_period);
assertEquals(DurationSpec.inSecondsString("14400s"), config.key_cache_save_period);
assertEquals(DurationSpec.inHours(4), config.key_cache_save_period);
assertEquals(DurationSpec.inSecondsString("0"), config.row_cache_save_period);
assertEquals(DurationSpec.inSeconds(0), config.row_cache_save_period);
assertEquals(DurationSpec.inHours(2), config.counter_cache_save_period);
assertEquals(DurationSpec.inSeconds(35), config.cache_load_timeout);
assertEquals(DurationSpec.IntSecondsBound.inSecondsString("14400"), config.key_cache_save_period);
assertEquals(DurationSpec.IntSecondsBound.inSecondsString("14400s"), config.key_cache_save_period);
assertEquals(new DurationSpec.IntSecondsBound(4, TimeUnit.HOURS), config.key_cache_save_period);
assertEquals(DurationSpec.IntSecondsBound.inSecondsString("0"), config.row_cache_save_period);
assertEquals(new DurationSpec.IntSecondsBound(0), config.row_cache_save_period);
assertEquals(new DurationSpec.IntSecondsBound(2, TimeUnit.HOURS), config.counter_cache_save_period);
assertEquals(new DurationSpec.IntSecondsBound(35), config.cache_load_timeout);
}
}

View File

@ -20,6 +20,7 @@ package org.apache.cassandra.config;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.MEBIBYTES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@ -38,81 +39,81 @@ public class ParseAndConvertUnitsTest
Config config = DatabaseDescriptor.loadConfig();
//Confirm duration parameters were successfully parsed with the default values in cassandra.yaml
assertEquals(DurationSpec.inMilliseconds(10800000), config.max_hint_window);
assertEquals(DurationSpec.inMilliseconds(0), config.native_transport_idle_timeout);
assertEquals(DurationSpec.inMilliseconds(10000), config.request_timeout);
assertEquals(DurationSpec.inMilliseconds(5000), config.read_request_timeout);
assertEquals(DurationSpec.inMilliseconds(10000), config.range_request_timeout);
assertEquals(DurationSpec.inMilliseconds(2000), config.write_request_timeout);
assertEquals(DurationSpec.inMilliseconds(5000), config.counter_write_request_timeout);
assertEquals(DurationSpec.inMilliseconds(1800), config.cas_contention_timeout);
assertEquals(DurationSpec.inMilliseconds(60000), config.truncate_request_timeout);
assertEquals(DurationSpec.inSeconds(300), config.streaming_keep_alive_period);
assertEquals(DurationSpec.inMilliseconds(500), config.slow_query_log_timeout);
assertEquals(DurationSpec.inMilliseconds(2000), config.internode_tcp_connect_timeout);
assertEquals(DurationSpec.inMilliseconds(30000), config.internode_tcp_user_timeout);
assertEquals(DurationSpec.inMilliseconds(0), config.commitlog_sync_group_window);
assertEquals(DurationSpec.inMilliseconds(0), config.commitlog_sync_period);
assertEquals(new DurationSpec.IntMillisecondsBound(10800000), config.max_hint_window);
assertEquals(new DurationSpec.LongMillisecondsBound(0), config.native_transport_idle_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(10000), config.request_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(5000), config.read_request_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(10000), config.range_request_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(2000), config.write_request_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(5000), config.counter_write_request_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(1800), config.cas_contention_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(60000), config.truncate_request_timeout);
assertEquals(new DurationSpec.IntSecondsBound(300), config.streaming_keep_alive_period);
assertEquals(new DurationSpec.LongMillisecondsBound(500), config.slow_query_log_timeout);
assertEquals(new DurationSpec.IntMillisecondsBound(2000), config.internode_tcp_connect_timeout);
assertEquals(new DurationSpec.IntMillisecondsBound(30000), config.internode_tcp_user_timeout);
assertEquals(new DurationSpec.IntMillisecondsBound(0), config.commitlog_sync_group_window);
assertEquals(new DurationSpec.IntMillisecondsBound(0), config.commitlog_sync_period);
assertNull(config.periodic_commitlog_sync_lag_block);
assertEquals(DurationSpec.inMilliseconds(250), config.cdc_free_space_check_interval);
assertEquals(DurationSpec.inMilliseconds(100), config.dynamic_snitch_update_interval);
assertEquals(DurationSpec.inMilliseconds(600000), config.dynamic_snitch_reset_interval);
assertEquals(DurationSpec.inMilliseconds(200), config.gc_log_threshold);
assertEquals(DurationSpec.inMilliseconds(10000), config.hints_flush_period);
assertEquals(DurationSpec.inMilliseconds(1000), config.gc_warn_threshold);
assertEquals(DurationSpec.inSeconds(86400), config.trace_type_query_ttl);
assertEquals(DurationSpec.inSeconds(604800), config.trace_type_repair_ttl);
assertEquals(DurationSpec.inMilliseconds(2000), config.permissions_validity);
assertEquals(new DurationSpec.IntMillisecondsBound(250), config.cdc_free_space_check_interval);
assertEquals(new DurationSpec.IntMillisecondsBound(100), config.dynamic_snitch_update_interval);
assertEquals(new DurationSpec.IntMillisecondsBound(600000), config.dynamic_snitch_reset_interval);
assertEquals(new DurationSpec.IntMillisecondsBound(200), config.gc_log_threshold);
assertEquals(new DurationSpec.IntMillisecondsBound(10000), config.hints_flush_period);
assertEquals(new DurationSpec.IntMillisecondsBound(1000), config.gc_warn_threshold);
assertEquals(new DurationSpec.IntSecondsBound(86400), config.trace_type_query_ttl);
assertEquals(new DurationSpec.IntSecondsBound(604800), config.trace_type_repair_ttl);
assertEquals(new DurationSpec.IntMillisecondsBound(2000), config.permissions_validity);
assertNull(config.permissions_update_interval);
assertEquals(DurationSpec.inMilliseconds(2000), config.roles_validity);
assertEquals(new DurationSpec.IntMillisecondsBound(2000), config.roles_validity);
assertNull(config.roles_update_interval);
assertEquals(DurationSpec.inMilliseconds(2000), config.credentials_validity);
assertEquals(new DurationSpec.IntMillisecondsBound(2000), config.credentials_validity);
assertNull(config.credentials_update_interval);
assertEquals(DurationSpec.inMinutes(60), config.index_summary_resize_interval);
assertEquals(DurationSpec.inHours(4), config.key_cache_save_period);
assertEquals(DurationSpec.inSeconds(30), config.cache_load_timeout);
assertEquals(DurationSpec.inMilliseconds(1500), config.user_defined_functions_fail_timeout);
assertEquals(DurationSpec.inMilliseconds(500), config.user_defined_functions_warn_timeout);
assertEquals(DurationSpec.inSeconds(3600), config.validation_preview_purge_head_start);
assertEquals(new DurationSpec.IntMinutesBound(60), config.index_summary_resize_interval);
assertEquals(DurationSpec.IntSecondsBound.inSecondsString("4h"), config.key_cache_save_period);
assertEquals(new DurationSpec.IntSecondsBound(30), config.cache_load_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(1500), config.user_defined_functions_fail_timeout);
assertEquals(new DurationSpec.LongMillisecondsBound(500), config.user_defined_functions_warn_timeout);
assertEquals(new DurationSpec.IntSecondsBound(3600), config.validation_preview_purge_head_start);
//Confirm space parameters were successfully parsed with the default values in cassandra.yaml
assertNull(config.memtable_heap_space);
assertNull(config.memtable_offheap_space);
assertNull(config.repair_session_space); //null everywhere so should be correct, let's check whether it will bomb
assertEquals(DataStorageSpec.inBytes(4194304), config.internode_application_send_queue_capacity);
assertEquals(DataStorageSpec.inBytes(134217728), config.internode_application_send_queue_reserve_endpoint_capacity);
assertEquals(DataStorageSpec.inBytes(536870912), config.internode_application_send_queue_reserve_global_capacity);
assertEquals(DataStorageSpec.inBytes(4194304), config.internode_application_receive_queue_capacity);
assertEquals(DataStorageSpec.inBytes(134217728), config.internode_application_receive_queue_reserve_endpoint_capacity);
assertEquals(DataStorageSpec.inBytes(536870912), config.internode_application_receive_queue_reserve_global_capacity);
assertEquals(DataStorageSpec.inMebibytes(16), config.native_transport_max_frame_size);
assertEquals(DataStorageSpec.inMebibytes(256), config.max_value_size);
assertEquals(DataStorageSpec.inKibibytes(4), config.column_index_size);
assertEquals(DataStorageSpec.inKibibytes(2), config.column_index_cache_size);
assertEquals(DataStorageSpec.inKibibytes(5), config.batch_size_warn_threshold);
assertEquals(DataStorageSpec.inKibibytes(50), config.batch_size_fail_threshold);
assertEquals(DataStorageSpec.inMebibytes(100), config.compaction_large_partition_warning_threshold);
assertEquals(new DataStorageSpec.IntBytesBound(4194304), config.internode_application_send_queue_capacity);
assertEquals(new DataStorageSpec.IntBytesBound(134217728), config.internode_application_send_queue_reserve_endpoint_capacity);
assertEquals(new DataStorageSpec.IntBytesBound(536870912), config.internode_application_send_queue_reserve_global_capacity);
assertEquals(new DataStorageSpec.IntBytesBound(4194304), config.internode_application_receive_queue_capacity);
assertEquals(new DataStorageSpec.IntBytesBound(134217728), config.internode_application_receive_queue_reserve_endpoint_capacity);
assertEquals(new DataStorageSpec.IntBytesBound(536870912), config.internode_application_receive_queue_reserve_global_capacity);
assertEquals(new DataStorageSpec.IntMebibytesBound(16), config.native_transport_max_frame_size);
assertEquals(new DataStorageSpec.IntMebibytesBound(256), config.max_value_size);
assertEquals(new DataStorageSpec.IntKibibytesBound(4), config.column_index_size);
assertEquals(new DataStorageSpec.IntKibibytesBound(2), config.column_index_cache_size);
assertEquals(new DataStorageSpec.IntKibibytesBound(5), config.batch_size_warn_threshold);
assertEquals(new DataStorageSpec.IntKibibytesBound(50), config.batch_size_fail_threshold);
assertEquals(new DataStorageSpec.IntMebibytesBound(100), config.compaction_large_partition_warning_threshold);
assertNull(config.commitlog_total_space);
assertEquals(DataStorageSpec.inMebibytes(5), config.commitlog_segment_size);
assertEquals(new DataStorageSpec.IntMebibytesBound(5), config.commitlog_segment_size);
assertNull(config.max_mutation_size); //not set explicitly in the default yaml, check the config; not set there too
assertEquals(DataStorageSpec.inMebibytes(0), config.cdc_total_space);
assertEquals(DataStorageSpec.inKibibytes(1024), config.hinted_handoff_throttle);
assertEquals(DataStorageSpec.inKibibytes(1024), config.batchlog_replay_throttle);
assertEquals(DataStorageSpec.inKibibytes(10240), config.trickle_fsync_interval);
assertEquals(DataStorageSpec.inMebibytes(50), config.sstable_preemptive_open_interval);
assertEquals(new DataStorageSpec.IntMebibytesBound(0), config.cdc_total_space);
assertEquals(new DataStorageSpec.IntKibibytesBound(1024), config.hinted_handoff_throttle);
assertEquals(new DataStorageSpec.IntKibibytesBound(1024), config.batchlog_replay_throttle);
assertEquals(new DataStorageSpec.IntKibibytesBound(10240), config.trickle_fsync_interval);
assertEquals(new DataStorageSpec.IntMebibytesBound(50), config.sstable_preemptive_open_interval);
assertNull(config.counter_cache_size);
assertNull(config.file_cache_size);
assertNull(config.index_summary_capacity);
assertEquals(DataStorageSpec.inMebibytes(1), config.prepared_statements_cache_size);
assertEquals(new DataStorageSpec.LongMebibytesBound(1), config.prepared_statements_cache_size);
assertNull(config.key_cache_size);
assertEquals(DataStorageSpec.inMebibytes(16), config.row_cache_size);
assertEquals(new DataStorageSpec.LongMebibytesBound(16), config.row_cache_size);
assertNull(config.native_transport_max_request_data_in_flight);
assertNull(config.native_transport_max_request_data_in_flight_per_ip);
assertEquals(DataStorageSpec.inMebibytes(1), config.native_transport_receive_queue_capacity);
assertEquals(new DataStorageSpec.IntBytesBound(1, MEBIBYTES), config.native_transport_receive_queue_capacity);
//Confirm rate parameters were successfully parsed with the default values in cassandra.yaml
assertEquals(DataRateSpec.inMebibytesPerSecond(0), config.compaction_throughput);
assertEquals(DataRateSpec.inMebibytesPerSecond(23841858), config.stream_throughput_outbound);
assertEquals(DataRateSpec.inMebibytesPerSecond(24), config.inter_dc_stream_throughput_outbound);
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound(0), config.compaction_throughput);
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound(23841858), config.stream_throughput_outbound);
assertEquals(new DataRateSpec.IntMebibytesPerSecondBound(24), config.inter_dc_stream_throughput_outbound);
}
}
}

View File

@ -73,7 +73,7 @@ public class PropertiesTest
ps.get("cluster_name").set(config, "properties testing");
assertThat(config.cluster_name).isEqualTo("properties testing");
ps.get("permissions_validity").set(config, SmallestDurationMilliseconds.inMilliseconds(42));
ps.get("permissions_validity").set(config, new DurationSpec.IntMillisecondsBound(42));
assertThat(config.permissions_validity.toMilliseconds()).isEqualTo(42);
ps.get("hinted_handoff_disabled_datacenters").set(config, Sets.newHashSet("a", "b", "c"));

View File

@ -1,40 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.config;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
public class SmallestDataStorageKibibytesTest
{
@Test
public void testInvalidUnits()
{
assertThatThrownBy(() -> new SmallestDataStorageKibibytes("10B")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 10B");
}
@Test
public void testValidUnits()
{
assertEquals(10L, new SmallestDataStorageKibibytes("10KiB").toKibibytes());
}
}

View File

@ -1,40 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.config;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
public class SmallestDataStorageMebibytesTest
{
@Test
public void testInvalidUnits()
{
assertThatThrownBy(() -> new SmallestDataStorageMebibytes("10B")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid data storage: 10B");
}
@Test
public void testValidUnits()
{
assertEquals(10L, new SmallestDataStorageMebibytes("10MiB").toMebibytes());
}
}

View File

@ -1,46 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.config;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
public class SmallestDurationMillisecondsTest
{
@Test
public void testInvalidUnits()
{
assertThatThrownBy(() -> new SmallestDurationMilliseconds("10ns")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ns");
assertThatThrownBy(() -> new SmallestDurationMilliseconds("10us")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10us");
assertThatThrownBy(() -> new SmallestDurationMilliseconds("10µs")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10µs");
assertThatThrownBy(() -> new SmallestDurationMilliseconds("-10s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: -10s");
}
@Test
public void testValidUnits()
{
assertEquals(10L, new SmallestDurationMilliseconds("10ms").toMilliseconds());
}
}

View File

@ -1,50 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.config;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
public class SmallestDurationMinutesTest
{
@Test
public void testInvalidUnits()
{
assertThatThrownBy(() -> new SmallestDurationMinutes("10s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10s");
assertThatThrownBy(() -> new SmallestDurationMinutes("10ms")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ms");
assertThatThrownBy(() -> new SmallestDurationMinutes("10ns")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ns");
assertThatThrownBy(() -> new SmallestDurationMinutes("10us")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10us");
assertThatThrownBy(() -> new SmallestDurationMinutes("10µs")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10µs");
assertThatThrownBy(() -> new SmallestDurationMinutes("-10s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: -10s");
}
@Test
public void testValidUnits()
{
assertEquals(10L, new SmallestDurationMinutes("10m").toMinutes());
}
}

View File

@ -1,48 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.config;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
public class SmallestDurationSecondsTest
{
@Test
public void testInvalidUnits()
{
assertThatThrownBy(() -> new SmallestDurationSeconds("10ms")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ms");
assertThatThrownBy(() -> new SmallestDurationSeconds("10ns")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10ns");
assertThatThrownBy(() -> new SmallestDurationSeconds("10us")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10us");
assertThatThrownBy(() -> new SmallestDurationSeconds("10µs")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: 10µs");
assertThatThrownBy(() -> new SmallestDurationSeconds("-10s")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid duration: -10s");
}
@Test
public void testValidUnits()
{
assertEquals(10L, new SmallestDurationSeconds("10s").toSeconds());
}
}

View File

@ -18,11 +18,14 @@
package org.apache.cassandra.config;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.function.Predicate;
import com.google.common.collect.ImmutableMap;
import org.junit.Test;
@ -32,6 +35,7 @@ import org.apache.cassandra.io.util.File;
import org.yaml.snakeyaml.error.YAMLException;
import static org.apache.cassandra.config.CassandraRelevantProperties.CONFIG_ALLOW_SYSTEM_PROPERTIES;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.KIBIBYTES;
import static org.apache.cassandra.config.YamlConfigurationLoader.SYSTEM_PROPERTY_PREFIX;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@ -41,6 +45,20 @@ import static org.junit.Assert.assertTrue;
public class YamlConfigurationLoaderTest
{
@Test
public void validateTypes()
{
Predicate<Field> isDurationSpec = f -> f.getType().getTypeName().equals("org.apache.cassandra.config.DurationSpec");
Predicate<Field> isDataStorageSpec = f -> f.getType().getTypeName().equals("org.apache.cassandra.config.DataStorageSpec");
Predicate<Field> isDataRateSpec = f -> f.getType().getTypeName().equals("org.apache.cassandra.config.DataRateSpec");
assertEquals("You have wrongly defined a config parameter of abstract type DurationSpec, DataStorageSpec or DataRateSpec." +
"Please check the config docs, otherwise Cassandra won't be able to start with this parameter being set in cassandra.yaml.",
Arrays.stream(Config.class.getFields())
.filter(f -> !Modifier.isStatic(f.getModifiers()))
.filter(isDurationSpec.or(isDataRateSpec).or(isDataStorageSpec)).count(), 0);
}
@Test
public void updateInPlace()
{
@ -99,14 +117,14 @@ public class YamlConfigurationLoaderTest
assertThat(c.read_thresholds_enabled).isTrue();
assertThat(c.coordinator_read_size_warn_threshold).isEqualTo(DataStorageSpec.inKibibytes(1 << 10));
assertThat(c.coordinator_read_size_fail_threshold).isEqualTo(DataStorageSpec.inKibibytes(1 << 12));
assertThat(c.coordinator_read_size_warn_threshold).isEqualTo(new DataStorageSpec.LongBytesBound(1 << 10, KIBIBYTES));
assertThat(c.coordinator_read_size_fail_threshold).isEqualTo(new DataStorageSpec.LongBytesBound(1 << 12, KIBIBYTES));
assertThat(c.local_read_size_warn_threshold).isEqualTo(DataStorageSpec.inKibibytes(1 << 12));
assertThat(c.local_read_size_fail_threshold).isEqualTo(DataStorageSpec.inKibibytes(1 << 13));
assertThat(c.local_read_size_warn_threshold).isEqualTo(new DataStorageSpec.LongBytesBound(1 << 12, KIBIBYTES));
assertThat(c.local_read_size_fail_threshold).isEqualTo(new DataStorageSpec.LongBytesBound(1 << 13, KIBIBYTES));
assertThat(c.row_index_read_size_warn_threshold).isEqualTo(DataStorageSpec.inKibibytes(1 << 12));
assertThat(c.row_index_read_size_fail_threshold).isEqualTo(DataStorageSpec.inKibibytes(1 << 13));
assertThat(c.row_index_read_size_warn_threshold).isEqualTo(new DataStorageSpec.LongBytesBound(1 << 12, KIBIBYTES));
assertThat(c.row_index_read_size_fail_threshold).isEqualTo(new DataStorageSpec.LongBytesBound(1 << 13, KIBIBYTES));
}
@Test
@ -124,14 +142,14 @@ public class YamlConfigurationLoaderTest
Config c = YamlConfigurationLoader.fromMap(map, Config.class);
assertThat(c.read_thresholds_enabled).isTrue();
assertThat(c.coordinator_read_size_warn_threshold).isEqualTo(DataStorageSpec.inKibibytes(1024));
assertThat(c.coordinator_read_size_warn_threshold).isEqualTo(new DataStorageSpec.LongBytesBound(1024, KIBIBYTES));
assertThat(c.coordinator_read_size_fail_threshold).isNull();
assertThat(c.local_read_size_warn_threshold).isNull();
assertThat(c.local_read_size_fail_threshold).isEqualTo(DataStorageSpec.inKibibytes(1024));
assertThat(c.local_read_size_fail_threshold).isEqualTo(new DataStorageSpec.LongBytesBound(1024, KIBIBYTES));
assertThat(c.row_index_read_size_warn_threshold).isEqualTo(DataStorageSpec.inKibibytes(1024));
assertThat(c.row_index_read_size_fail_threshold).isEqualTo(DataStorageSpec.inKibibytes(1024));
assertThat(c.row_index_read_size_warn_threshold).isEqualTo(new DataStorageSpec.LongBytesBound(1024, KIBIBYTES));
assertThat(c.row_index_read_size_fail_threshold).isEqualTo(new DataStorageSpec.LongBytesBound(1024, KIBIBYTES));
}
@Test
@ -181,8 +199,8 @@ public class YamlConfigurationLoaderTest
assertEquals(seedProvider, config.seed_provider); // Check a parameterized class
assertEquals(false, config.client_encryption_options.optional); // Check a nested object
assertEquals(true, config.client_encryption_options.enabled); // Check a nested object
assertEquals(new DataStorageSpec("5B"), config.internode_socket_send_buffer_size); // Check names backward compatibility (CASSANDRA-17141 and CASSANDRA-15234)
assertEquals(new DataStorageSpec("5B"), config.internode_socket_receive_buffer_size); // Check names backward compatibility (CASSANDRA-17141 and CASSANDRA-15234)
assertEquals(new DataStorageSpec.IntBytesBound("5B"), config.internode_socket_send_buffer_size); // Check names backward compatibility (CASSANDRA-17141 and CASSANDRA-15234)
assertEquals(new DataStorageSpec.IntBytesBound("5B"), config.internode_socket_receive_buffer_size); // Check names backward compatibility (CASSANDRA-17141 and CASSANDRA-15234)
}
@Test
@ -194,9 +212,9 @@ public class YamlConfigurationLoaderTest
Config latest = YamlConfigurationLoader.fromMap(ImmutableMap.of("key_cache_save_period", "42s",
"row_cache_save_period", "42s",
"counter_cache_save_period", "42s"), Config.class);
assertThat(old.key_cache_save_period).isEqualTo(latest.key_cache_save_period).isEqualTo(SmallestDurationSeconds.inSeconds(42));
assertThat(old.row_cache_save_period).isEqualTo(latest.row_cache_save_period).isEqualTo(SmallestDurationSeconds.inSeconds(42));
assertThat(old.counter_cache_save_period).isEqualTo(latest.counter_cache_save_period).isEqualTo(SmallestDurationSeconds.inSeconds(42));
assertThat(old.key_cache_save_period).isEqualTo(latest.key_cache_save_period).isEqualTo(new DurationSpec.IntSecondsBound(42));
assertThat(old.row_cache_save_period).isEqualTo(latest.row_cache_save_period).isEqualTo(new DurationSpec.IntSecondsBound(42));
assertThat(old.counter_cache_save_period).isEqualTo(latest.counter_cache_save_period).isEqualTo(new DurationSpec.IntSecondsBound(42));
}
@Test
@ -224,20 +242,20 @@ public class YamlConfigurationLoaderTest
assertThat(from("commitlog_sync_group_window_in_ms", "NaN").commitlog_sync_group_window.toMilliseconds()).isEqualTo(0);
assertThatThrownBy(() -> from("commitlog_sync_group_window_in_ms", -2).commitlog_sync_group_window.toMilliseconds())
.hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("Invalid duration -2: value must be positive");
.hasRootCauseMessage("Invalid duration: value must be non-negative");
// MILLIS_CUSTOM_DURATION
assertThat(from("permissions_update_interval_in_ms", 42).permissions_update_interval).isEqualTo(SmallestDurationMilliseconds.inMilliseconds(42));
assertThat(from("permissions_update_interval_in_ms", 42).permissions_update_interval).isEqualTo(new DurationSpec.IntMillisecondsBound(42));
assertThat(from("permissions_update_interval_in_ms", -1).permissions_update_interval).isNull();
assertThatThrownBy(() -> from("permissions_update_interval_in_ms", -2))
.hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("Invalid duration -2: value must be positive");
.hasRootCauseMessage("Invalid duration: value must be non-negative");
// SECONDS_DURATION
assertThat(from("streaming_keep_alive_period_in_secs", "42").streaming_keep_alive_period.toSeconds()).isEqualTo(42);
assertThatThrownBy(() -> from("streaming_keep_alive_period_in_secs", -2).streaming_keep_alive_period.toSeconds())
.hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("Invalid duration -2: value must be positive");
.hasRootCauseMessage("Invalid duration: value must be non-negative");
// NEGATIVE_SECONDS_DURATION
assertThat(from("validation_preview_purge_head_start_in_sec", -1).validation_preview_purge_head_start.toSeconds()).isEqualTo(0);
@ -250,7 +268,7 @@ public class YamlConfigurationLoaderTest
assertThat(from("index_summary_resize_interval_in_minutes", "42").index_summary_resize_interval.toMinutes()).isEqualTo(42);
assertThatThrownBy(() -> from("index_summary_resize_interval_in_minutes", -2).index_summary_resize_interval.toMinutes())
.hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("Invalid duration -2: value must be positive");
.hasRootCauseMessage("Invalid duration: value must be non-negative");
// BYTES_CUSTOM_DATASTORAGE
assertThat(from("native_transport_max_concurrent_requests_in_bytes_per_ip", -1).native_transport_max_request_data_in_flight_per_ip).isEqualTo(null);
@ -261,37 +279,37 @@ public class YamlConfigurationLoaderTest
assertThat(from("memtable_heap_space_in_mb", "42").memtable_heap_space.toMebibytes()).isEqualTo(42);
assertThatThrownBy(() -> from("memtable_heap_space_in_mb", -2).memtable_heap_space.toMebibytes())
.hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("Invalid data storage: value must be positive, but was -2");
.hasRootCauseMessage("Invalid data storage: value must be non-negative");
// KIBIBYTES_DATASTORAGE
assertThat(from("column_index_size_in_kb", "42").column_index_size.toKibibytes()).isEqualTo(42);
assertThatThrownBy(() -> from("column_index_size_in_kb", -2).column_index_size.toMebibytes())
assertThatThrownBy(() -> from("column_index_size_in_kb", -2).column_index_size.toKibibytes())
.hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("Invalid data storage: value must be positive, but was -2");
.hasRootCauseMessage("Invalid data storage: value must be non-negative");
// BYTES_DATASTORAGE
assertThat(from("internode_max_message_size_in_bytes", "42").internode_max_message_size.toBytes()).isEqualTo(42);
assertThatThrownBy(() -> from("internode_max_message_size_in_bytes", -2).internode_max_message_size.toBytes())
.hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("Invalid data storage: value must be positive, but was -2");
.hasRootCauseMessage("Invalid data storage: value must be non-negative");
// BYTES_DATASTORAGE
assertThat(from("internode_max_message_size_in_bytes", "42").internode_max_message_size.toBytes()).isEqualTo(42);
assertThatThrownBy(() -> from("internode_max_message_size_in_bytes", -2).internode_max_message_size.toBytes())
.hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("Invalid data storage: value must be positive, but was -2");
.hasRootCauseMessage("Invalid data storage: value must be non-negative");
// MEBIBYTES_PER_SECOND_DATA_RATE
assertThat(from("compaction_throughput_mb_per_sec", "42").compaction_throughput.toMebibytesPerSecondAsInt()).isEqualTo(42);
assertThatThrownBy(() -> from("compaction_throughput_mb_per_sec", -2).compaction_throughput.toMebibytesPerSecondAsInt())
.hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("Invalid bit rate: value must be non-negative");
.hasRootCauseMessage("Invalid data rate: value must be non-negative");
// MEGABITS_TO_MEBIBYTES_PER_SECOND_DATA_RATE
assertThat(from("stream_throughput_outbound_megabits_per_sec", "42").stream_throughput_outbound.toMegabitsPerSecondAsInt()).isEqualTo(42);
assertThatThrownBy(() -> from("stream_throughput_outbound_megabits_per_sec", -2).stream_throughput_outbound.toMegabitsPerSecondAsInt())
.hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("Invalid bit rate: value must be non-negative");
.hasRootCauseMessage("Invalid data rate: value must be non-negative");
}
private static Config from(Object... values)

View File

@ -68,8 +68,8 @@ import org.apache.cassandra.auth.AuthTestUtils;
import org.apache.cassandra.auth.IRoleManager;
import org.apache.cassandra.concurrent.ScheduledExecutors;
import org.apache.cassandra.concurrent.Stage;
import org.apache.cassandra.config.DataStorageSpec;
import org.apache.cassandra.config.EncryptionOptions;
import org.apache.cassandra.config.SmallestDataStorageMebibytes;
import org.apache.cassandra.db.virtual.VirtualKeyspaceRegistry;
import org.apache.cassandra.db.virtual.VirtualSchemaKeyspace;
import org.apache.cassandra.exceptions.InvalidRequestException;
@ -131,7 +131,7 @@ public abstract class CQLTester
public static final String KEYSPACE_PER_TEST = "cql_test_keyspace_alt";
protected static final boolean USE_PREPARED_VALUES = Boolean.valueOf(System.getProperty("cassandra.test.use_prepared", "true"));
protected static final boolean REUSE_PREPARED = Boolean.valueOf(System.getProperty("cassandra.test.reuse_prepared", "true"));
protected static final long ROW_CACHE_SIZE_IN_MIB = new SmallestDataStorageMebibytes(System.getProperty("cassandra.test.row_cache_size", "0MiB")).toMebibytes();
protected static final long ROW_CACHE_SIZE_IN_MIB = new DataStorageSpec.LongMebibytesBound(System.getProperty("cassandra.test.row_cache_size", "0MiB")).toMebibytes();
private static final AtomicInteger seqNumber = new AtomicInteger();
protected static final ByteBuffer TOO_BIG = ByteBuffer.allocate(FBUtilities.MAX_UNSIGNED_SHORT + 1024);
public static final String DATA_CENTER = ServerTestUtils.DATA_CENTER;

View File

@ -38,6 +38,7 @@ import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.service.snapshot.TableSnapshot;
import org.assertj.core.api.Condition;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.cassandra.db.ColumnFamilyStore.SNAPSHOT_DROP_PREFIX;
import static org.assertj.core.api.Assertions.assertThat;
@ -47,7 +48,7 @@ public class AutoSnapshotTest extends CQLTester
static int TTL_SECS = 1;
public static Boolean enabledBefore;
public static DurationSpec ttlBefore;
public static DurationSpec.IntSecondsBound ttlBefore;
@BeforeClass
public static void beforeClass()
@ -68,7 +69,7 @@ public class AutoSnapshotTest extends CQLTester
public Boolean autoSnapshotEnabled;
@Parameterized.Parameter(1)
public DurationSpec autoSnapshotTTl;
public DurationSpec.IntSecondsBound autoSnapshotTTl;
@Before
public void beforeTest() throws Throwable
@ -83,8 +84,8 @@ public class AutoSnapshotTest extends CQLTester
@Parameterized.Parameters( name = "enabled={0},ttl={1}" )
public static Collection options() {
return Arrays.asList(new Object[][] {
{ true, DurationSpec.inSeconds(TTL_SECS) },
{ false, DurationSpec.inSeconds(TTL_SECS) },
{ true, new DurationSpec.IntSecondsBound(TTL_SECS, SECONDS) },
{ false, new DurationSpec.IntSecondsBound(TTL_SECS, SECONDS) },
{ true, null },
{ false, null },
});
@ -149,7 +150,7 @@ public class AutoSnapshotTest extends CQLTester
{
// check that snapshot has TTL and is expired after 1 second
assertThat(snapshot.isExpiring()).isTrue();
Uninterruptibles.sleepUninterruptibly(TTL_SECS, TimeUnit.SECONDS);
Uninterruptibles.sleepUninterruptibly(TTL_SECS, SECONDS);
assertThat(snapshot.isExpired(Instant.now())).isTrue();
}
}

View File

@ -225,7 +225,7 @@ public class DirectoriesTest
if (createManifest)
{
File manifestFile = Directories.getSnapshotManifestFile(snapshotDir);
manifest = new SnapshotManifest(Collections.singletonList(sstableDesc.filenameFor(Component.DATA)), new DurationSpec("1m"), now());
manifest = new SnapshotManifest(Collections.singletonList(sstableDesc.filenameFor(Component.DATA)), new DurationSpec.IntSecondsBound("1m"), now());
manifest.serializeToJsonFile(manifestFile);
}
@ -353,7 +353,7 @@ public class DirectoriesTest
File manifestFile = directories.getSnapshotManifestFile(tag);
SnapshotManifest manifest = new SnapshotManifest(files, new DurationSpec("1m"), now());
SnapshotManifest manifest = new SnapshotManifest(files, new DurationSpec.IntSecondsBound("1m"), now());
manifest.serializeToJsonFile(manifestFile);
Set<File> dirs = new HashSet<>();

View File

@ -54,7 +54,7 @@ public class TopPartitionTrackerTest extends CQLTester
{
createTable("create table %s (id bigint primary key, x int)");
DatabaseDescriptor.setMaxTopSizePartitionCount(5);
DatabaseDescriptor.setMinTrackedPartitionSize(new DataStorageSpec("12B"));
DatabaseDescriptor.setMinTrackedPartitionSize(new DataStorageSpec.LongBytesBound("12B"));
Collection<Range<Token>> fullRange = Collections.singleton(r(0, 0));
TopPartitionTracker tpt = new TopPartitionTracker(getCurrentColumnFamilyStore().metadata());
@ -85,7 +85,7 @@ public class TopPartitionTrackerTest extends CQLTester
public void testCountLimit()
{
createTable("create table %s (id bigint primary key, x int)");
DatabaseDescriptor.setMinTrackedPartitionSize(new DataStorageSpec("0B"));
DatabaseDescriptor.setMinTrackedPartitionSize(new DataStorageSpec.LongBytesBound("0B"));
DatabaseDescriptor.setMaxTopSizePartitionCount(5);
Collection<Range<Token>> fullRange = Collections.singleton(r(0, 0));
TopPartitionTracker tpt = new TopPartitionTracker(getCurrentColumnFamilyStore().metadata());
@ -111,7 +111,7 @@ public class TopPartitionTrackerTest extends CQLTester
public void testSubRangeMerge()
{
createTable("create table %s (id bigint primary key, x int)");
DatabaseDescriptor.setMinTrackedPartitionSize(new DataStorageSpec("0B"));
DatabaseDescriptor.setMinTrackedPartitionSize(new DataStorageSpec.LongBytesBound("0B"));
DatabaseDescriptor.setMaxTopSizePartitionCount(10);
Collection<Range<Token>> fullRange = Collections.singleton(r(0, 0));
TopPartitionTracker tpt = new TopPartitionTracker(getCurrentColumnFamilyStore().metadata());
@ -140,7 +140,7 @@ public class TopPartitionTrackerTest extends CQLTester
public void testSaveLoad()
{
createTable("create table %s (id bigint primary key, x int)");
DatabaseDescriptor.setMinTrackedPartitionSize(new DataStorageSpec("0B"));
DatabaseDescriptor.setMinTrackedPartitionSize(new DataStorageSpec.LongBytesBound("0B"));
DatabaseDescriptor.setMinTrackedPartitionTombstoneCount(0);
DatabaseDescriptor.setMaxTopSizePartitionCount(10);
DatabaseDescriptor.setMaxTopTombstonePartitionCount(10);
@ -205,7 +205,7 @@ public class TopPartitionTrackerTest extends CQLTester
public void randomTest()
{
createTable("create table %s (id bigint primary key, x int)");
DatabaseDescriptor.setMinTrackedPartitionSize(new DataStorageSpec("0B"));
DatabaseDescriptor.setMinTrackedPartitionSize(new DataStorageSpec.LongBytesBound("0B"));
DatabaseDescriptor.setMaxTopSizePartitionCount(1000);
int keyCount = 10000;
long seed = System.currentTimeMillis();
@ -254,7 +254,7 @@ public class TopPartitionTrackerTest extends CQLTester
public void testRanges() throws UnknownHostException
{
createTable("create table %s (id bigint primary key, x int)");
DatabaseDescriptor.setMinTrackedPartitionSize(new DataStorageSpec("0B"));
DatabaseDescriptor.setMinTrackedPartitionSize(new DataStorageSpec.LongBytesBound("0B"));
DatabaseDescriptor.setMaxTopSizePartitionCount(1000);
long seed = System.currentTimeMillis();
Random r = new Random(seed);

View File

@ -122,7 +122,8 @@ public class GuardrailDiskUsageTest extends GuardrailTester
String message = String.format("only %s are actually available on disk", FileUtils.stringifyFileSize(diskSize));
assertConfigValid(x -> x.setDataDiskUsageMaxDiskSize(diskSize + "B"));
assertConfigFails(x -> x.setDataDiskUsageMaxDiskSize(diskSize + 1 + "B"), message);
assertConfigFails(x -> x.setDataDiskUsageMaxDiskSize(Long.MAX_VALUE + "GiB"), message);
// We want to test with very big number, Long.MAX_VALUE is not allowed so it was easy to use Intger.MAX_VALUE
assertConfigFails(x -> x.setDataDiskUsageMaxDiskSize(Integer.MAX_VALUE + "GiB"), message);
// warn threshold smaller than lower bound
assertConfigFails(x -> x.setDataDiskUsagePercentageThreshold(0, 80), "0 is not allowed");
@ -319,10 +320,10 @@ public class GuardrailDiskUsageTest extends GuardrailTester
public void testDiskUsageCalculationWithMaxDiskSize() throws IOException
{
Directories.DataDirectory directory = mock(Directories.DataDirectory.class);
when(directory.getRawSize()).thenReturn(DataStorageSpec.inGibibytes(5).toBytes());
when(directory.getRawSize()).thenReturn(new DataStorageSpec.LongBytesBound("5GiB").toBytes());
FileStore store = mock(FileStore.class);
when(store.getUsableSpace()).thenReturn(DataStorageSpec.inGibibytes(100 - 5).toBytes()); // 100GiB disk
when(store.getUsableSpace()).thenReturn(new DataStorageSpec.LongBytesBound("95GiB").toBytes()); // 100GiB disk - 5GiB
Multimap<FileStore, Directories.DataDirectory> directories = HashMultimap.create();
directories.put(store, directory);
@ -351,13 +352,13 @@ public class GuardrailDiskUsageTest extends GuardrailTester
public void testDiskUsageCalculationWithMaxDiskSizeAndSmallUnits() throws IOException
{
// 5GiB used out of 100GiB disk
long freeDiskSizeInBytes = DataStorageSpec.inGibibytes(100).toBytes() - DataStorageSpec.inMebibytes(5).toBytes();
long freeDiskSizeInBytes = new DataStorageSpec.LongBytesBound("100GiB").toBytes() - new DataStorageSpec.LongBytesBound("5MiB").toBytes();
FileStore store = mock(FileStore.class);
when(store.getUsableSpace()).thenReturn(DataStorageSpec.inBytes(freeDiskSizeInBytes).toBytes()); // 100GiB disk
when(store.getUsableSpace()).thenReturn(new DataStorageSpec.LongBytesBound(freeDiskSizeInBytes + "B").toBytes()); // 100GiB disk
Directories.DataDirectory directory = mock(Directories.DataDirectory.class);
when(directory.getRawSize()).thenReturn(DataStorageSpec.inMebibytes(5).toBytes());
when(directory.getRawSize()).thenReturn(new DataStorageSpec.LongBytesBound("5MiB").toBytes());
Multimap<FileStore, Directories.DataDirectory> directories = HashMultimap.create();
directories.put(store, directory);
@ -391,20 +392,20 @@ public class GuardrailDiskUsageTest extends GuardrailTester
Directories.DataDirectory directory1 = mock(Directories.DataDirectory.class);
FileStore store1 = mock(FileStore.class);
when(directory1.getRawSize()).thenReturn(DataStorageSpec.inGibibytes(5).toBytes());
when(store1.getUsableSpace()).thenReturn(DataStorageSpec.inGibibytes(100 - 5).toBytes()); // 100 GiB disk
when(directory1.getRawSize()).thenReturn(new DataStorageSpec.LongBytesBound("5GiB").toBytes());
when(store1.getUsableSpace()).thenReturn(new DataStorageSpec.LongBytesBound("95GiB").toBytes()); // 100 GiB disk - 5 GiB
directories.put(store1, directory1);
Directories.DataDirectory directory2 = mock(Directories.DataDirectory.class);
FileStore store2 = mock(FileStore.class);
when(directory2.getRawSize()).thenReturn(DataStorageSpec.inGibibytes(25).toBytes());
when(store2.getUsableSpace()).thenReturn(DataStorageSpec.inGibibytes(100 - 25).toBytes()); // 100 GiB disk
when(directory2.getRawSize()).thenReturn(new DataStorageSpec.LongBytesBound("25GiB").toBytes());
when(store2.getUsableSpace()).thenReturn(new DataStorageSpec.LongBytesBound("75GiB").toBytes()); // 100 GiB disk - 25 GiB
directories.put(store2, directory2);
Directories.DataDirectory directory3 = mock(Directories.DataDirectory.class);
FileStore store3 = mock(FileStore.class);
when(directory3.getRawSize()).thenReturn(DataStorageSpec.inGibibytes(20).toBytes());
when(store3.getUsableSpace()).thenReturn(DataStorageSpec.inGibibytes(100 - 20).toBytes()); // 100 GiB disk
when(directory3.getRawSize()).thenReturn(new DataStorageSpec.LongBytesBound("20GiB").toBytes());
when(store3.getUsableSpace()).thenReturn(new DataStorageSpec.LongBytesBound("80GiB").toBytes()); // 100 GiB disk - 20 GiB
directories.put(store3, directory3);
DiskUsageMonitor monitor = spy(new DiskUsageMonitor(() -> directories));
@ -439,16 +440,16 @@ public class GuardrailDiskUsageTest extends GuardrailTester
Mockito.reset();
Directories.DataDirectory directory1 = mock(Directories.DataDirectory.class);
when(directory1.getRawSize()).thenReturn(DataStorageSpec.inGibibytes(5).toBytes());
when(directory1.getRawSize()).thenReturn(new DataStorageSpec.LongBytesBound("5GiB").toBytes());
Directories.DataDirectory directory2 = mock(Directories.DataDirectory.class);
when(directory2.getRawSize()).thenReturn(DataStorageSpec.inGibibytes(25).toBytes());
when(directory2.getRawSize()).thenReturn(new DataStorageSpec.LongBytesBound("25GiB").toBytes());
Directories.DataDirectory directory3 = mock(Directories.DataDirectory.class);
when(directory3.getRawSize()).thenReturn(DataStorageSpec.inGibibytes(20).toBytes());
when(directory3.getRawSize()).thenReturn(new DataStorageSpec.LongBytesBound("20GiB").toBytes());
FileStore store = mock(FileStore.class);
when(store.getUsableSpace()).thenReturn(DataStorageSpec.inGibibytes(300 - 5 - 25 - 20).toBytes()); // 100 GiB disk
when(store.getUsableSpace()).thenReturn(new DataStorageSpec.LongBytesBound("250GiB").toBytes()); // 100 GiB disk (300 - 5 - 25 - 20)
Multimap<FileStore, Directories.DataDirectory> directories = HashMultimap.create();
directories.putAll(store, ImmutableSet.of(directory1, directory2, directory3));

View File

@ -32,6 +32,7 @@ import org.apache.cassandra.config.DataStorageSpec;
import org.assertj.core.api.Assertions;
import static java.lang.String.format;
import static org.apache.cassandra.config.DataStorageSpec.DataStorageUnit.BYTES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
@ -91,12 +92,12 @@ public abstract class ThresholdTester extends GuardrailTester
Function<Guardrails, String> failGetter)
{
super(threshold);
this.warnThreshold = new DataStorageSpec(warnThreshold).toBytes();
this.failThreshold = new DataStorageSpec(failThreshold).toBytes();
this.setter = (g, w, a) -> setter.accept(g, w == null ? null : DataStorageSpec.inBytes(w).toString(), a == null ? null : DataStorageSpec.inBytes(a).toString());
this.warnGetter = g -> new DataStorageSpec(warnGetter.apply(g)).toBytes();
this.failGetter = g -> new DataStorageSpec(failGetter.apply(g)).toBytes();
maxValue = Long.MAX_VALUE;
this.warnThreshold = new DataStorageSpec.LongBytesBound(warnThreshold).toBytes();
this.failThreshold = new DataStorageSpec.LongBytesBound(failThreshold).toBytes();
this.setter = (g, w, a) -> setter.accept(g, w == null ? null : new DataStorageSpec.LongBytesBound(w, BYTES).toString(), a == null ? null : new DataStorageSpec.LongBytesBound(a, BYTES).toString());
this.warnGetter = g -> new DataStorageSpec.LongBytesBound(warnGetter.apply(g)).toBytes();
this.failGetter = g -> new DataStorageSpec.LongBytesBound(failGetter.apply(g)).toBytes();
maxValue = Long.MAX_VALUE - 1;
disabledValue = null;
}
@ -246,7 +247,7 @@ public abstract class ThresholdTester extends GuardrailTester
value, name, disabledValue);
if (expectedMessage == null && value < 0)
expectedMessage = format("Invalid data storage: value must be positive, but was %d", value);
expectedMessage = format("Invalid data storage: value must be non-negative");
assertEquals(format("Exception message '%s' does not contain '%s'", e.getMessage(), expectedMessage),
expectedMessage, e.getMessage());

View File

@ -74,7 +74,7 @@ public class CredentialsCacheKeysTableTest extends CQLTester
@AfterClass
public static void tearDownClass()
{
DatabaseDescriptor.setCredentialsValidity(DatabaseDescriptor.getRawConfig().credentials_validity.toMillisecondsAsInt());
DatabaseDescriptor.setCredentialsValidity(DatabaseDescriptor.getRawConfig().credentials_validity.toMilliseconds());
}
@Test

View File

@ -95,7 +95,7 @@ public class JmxPermissionsCacheKeysTableTest extends CQLTester
@AfterClass
public static void tearDownClass()
{
DatabaseDescriptor.setPermissionsValidity(DatabaseDescriptor.getRawConfig().permissions_validity.toMillisecondsAsInt());
DatabaseDescriptor.setPermissionsValidity(DatabaseDescriptor.getRawConfig().permissions_validity.toMilliseconds());
}
@Test

View File

@ -75,7 +75,7 @@ public class NetworkPermissionsCacheKeysTableTest extends CQLTester
@AfterClass
public static void tearDownClass()
{
DatabaseDescriptor.setPermissionsValidity(DatabaseDescriptor.getRawConfig().permissions_validity.toMillisecondsAsInt());
DatabaseDescriptor.setPermissionsValidity(DatabaseDescriptor.getRawConfig().permissions_validity.toMilliseconds());
}
@Test

View File

@ -90,7 +90,7 @@ public class PermissionsCacheKeysTableTest extends CQLTester
@AfterClass
public static void tearDownClass()
{
DatabaseDescriptor.setPermissionsValidity(DatabaseDescriptor.getRawConfig().permissions_validity.toMillisecondsAsInt());
DatabaseDescriptor.setPermissionsValidity(DatabaseDescriptor.getRawConfig().permissions_validity.toMilliseconds());
}
@Test

View File

@ -75,7 +75,7 @@ public class RolesCacheKeysTableTest extends CQLTester
@AfterClass
public static void tearDownClass()
{
DatabaseDescriptor.setRolesValidity(DatabaseDescriptor.getRawConfig().roles_validity.toMillisecondsAsInt());
DatabaseDescriptor.setRolesValidity(DatabaseDescriptor.getRawConfig().roles_validity.toMilliseconds());
}
@Test

View File

@ -154,7 +154,7 @@ public class SnapshotLoaderTest
// Write manifest for snapshot tag2 on random location
Instant tag2Ts = Instant.now().plusSeconds(10);
DurationSpec tag2Ttl = new DurationSpec("10h");
DurationSpec.IntSecondsBound tag2Ttl = new DurationSpec.IntSecondsBound("10h");
File tag2ManifestLocation = tag2Files.toArray(new File[0])[ThreadLocalRandom.current().nextInt(tag2Files.size())];
writeManifest(tag2ManifestLocation, tag2Ts, tag2Ttl);
@ -206,7 +206,7 @@ public class SnapshotLoaderTest
assertThat(SnapshotLoader.parseUUID("c7e513243f0711ec9bbc0242ac130002")).isEqualTo(UUID.fromString("c7e51324-3f07-11ec-9bbc-0242ac130002"));
}
private void writeManifest(File snapshotDir, Instant creationTime, DurationSpec ttl) throws IOException
private void writeManifest(File snapshotDir, Instant creationTime, DurationSpec.IntSecondsBound ttl) throws IOException
{
SnapshotManifest manifest = new SnapshotManifest(Lists.newArrayList("f1", "f2", "f3"), ttl, creationTime);
manifest.serializeToJsonFile(getManifestFile(snapshotDir));

View File

@ -108,7 +108,7 @@ public class SnapshotManifestTest
@Test
public void testSerializeAndDeserialize() throws Exception {
SnapshotManifest manifest = new SnapshotManifest(Arrays.asList("db1", "db2", "db3"), new DurationSpec("2m"), Instant.ofEpochMilli(currentTimeMillis()));
SnapshotManifest manifest = new SnapshotManifest(Arrays.asList("db1", "db2", "db3"), new DurationSpec.IntSecondsBound("2m"), Instant.ofEpochMilli(currentTimeMillis()));
File manifestFile = new File(tempFolder.newFile("manifest.json"));
manifest.serializeToJsonFile(manifestFile);

View File

@ -34,14 +34,15 @@ public class StreamManagerTest
{
private static double defaultStreamThroughputMebibytesPerSec;
private static double defaultInterDCStreamThroughputMebibytesPerSec;
private static final double INTEGER_MAX_VALUE_MEGABITS_IN_MEBIBYTES = DataRateSpec
.megabitsPerSecondInMebibytesPerSecond(Integer.MAX_VALUE)
.toMebibytesPerSecond();
private static final int MAX_INT_CONFIG_VALUE = Integer.MAX_VALUE - 1;
private static final double INTEGER_MAX_VALUE_MEGABITS_IN_MEBIBYTES = DataRateSpec.IntMebibytesPerSecondBound
.megabitsPerSecondInMebibytesPerSecond(MAX_INT_CONFIG_VALUE)
.toMebibytesPerSecond();
private static double defaultEntireSSTableStreamThroughputMebibytesPerSec;
private static double defaultEntireSSTableInterDCStreamThroughputMebibytesPerSec;
final double MEBIBYTES_PER_MEGABIT = 0.119209289550781;
private static final double MEBIBYTES_PER_MEGABIT = 0.119209289550781;
@BeforeClass
public static void setupClass()
@ -67,7 +68,7 @@ public class StreamManagerTest
assertEquals(500 * MEBIBYTES_PER_MEGABIT * BYTES_PER_MEBIBYTE, StreamRateLimiter.getRateLimiterRateInBytes(), 0);
// Max positive value check
StorageService.instance.setStreamThroughputMbitPerSec(Integer.MAX_VALUE);
StorageService.instance.setStreamThroughputMbitPerSec(MAX_INT_CONFIG_VALUE);
assertEquals(INTEGER_MAX_VALUE_MEGABITS_IN_MEBIBYTES * BYTES_PER_MEBIBYTE, StreamRateLimiter.getRateLimiterRateInBytes(), 0.04);
// Zero value check
@ -86,8 +87,8 @@ public class StreamManagerTest
assertEquals(1500d * BYTES_PER_MEBIBYTE, Math.round(StreamRateLimiter.getEntireSSTableRateLimiterRateInBytes()), 0);
// Max positive value check
StorageService.instance.setEntireSSTableStreamThroughputMebibytesPerSec(Integer.MAX_VALUE);
assertEquals(Integer.MAX_VALUE * BYTES_PER_MEBIBYTE, StreamRateLimiter.getEntireSSTableRateLimiterRateInBytes(), 0);
StorageService.instance.setEntireSSTableStreamThroughputMebibytesPerSec(MAX_INT_CONFIG_VALUE);
assertEquals((MAX_INT_CONFIG_VALUE) * BYTES_PER_MEBIBYTE, StreamRateLimiter.getEntireSSTableRateLimiterRateInBytes(), 0);
// Zero value check
StorageService.instance.setEntireSSTableStreamThroughputMebibytesPerSec(0);
@ -105,7 +106,7 @@ public class StreamManagerTest
assertEquals(200 * MEBIBYTES_PER_MEGABIT * BYTES_PER_MEBIBYTE, StreamRateLimiter.getInterDCRateLimiterRateInBytes(), 0);
// Max positive value check
StorageService.instance.setInterDCStreamThroughputMbitPerSec(Integer.MAX_VALUE);
StorageService.instance.setInterDCStreamThroughputMbitPerSec(MAX_INT_CONFIG_VALUE);
assertEquals(INTEGER_MAX_VALUE_MEGABITS_IN_MEBIBYTES * BYTES_PER_MEBIBYTE, StreamRateLimiter.getInterDCRateLimiterRateInBytes(), 0.04);
// Zero value check
@ -124,8 +125,8 @@ public class StreamManagerTest
assertEquals(1200.0d * BYTES_PER_MEBIBYTE, StreamRateLimiter.getEntireSSTableInterDCRateLimiterRateInBytes(), 0);
// Max positive value check
StorageService.instance.setEntireSSTableInterDCStreamThroughputMebibytesPerSec(Integer.MAX_VALUE);
assertEquals(Integer.MAX_VALUE * BYTES_PER_MEBIBYTE, StreamRateLimiter.getEntireSSTableInterDCRateLimiterRateInBytes(), 0);
StorageService.instance.setEntireSSTableInterDCStreamThroughputMebibytesPerSec(MAX_INT_CONFIG_VALUE);
assertEquals((MAX_INT_CONFIG_VALUE) * BYTES_PER_MEBIBYTE, StreamRateLimiter.getEntireSSTableInterDCRateLimiterRateInBytes(), 0);
// Zero value check
StorageService.instance.setEntireSSTableInterDCStreamThroughputMebibytesPerSec(0);

View File

@ -66,13 +66,13 @@ public class SetGetColumnIndexSizeTest extends CQLTester
@Test
public void testNegative()
{
assertSetInvalidColumnIndexSize("-7", "Invalid data storage: value must be positive, but was -7", 1);
assertSetInvalidColumnIndexSize("-7", "Invalid data storage: value must be non-negative", 1);
}
@Test
public void testInvalidValue()
{
assertSetInvalidColumnIndexSize("2097152", "column_index_size must be positive value <= 2147483647B, but was 2147483648B", 2);
assertSetInvalidColumnIndexSize("2097152", "column_index_size must be positive value <= 2147483646B, but was 2147483647B", 2);
}
@Test

View File

@ -53,7 +53,7 @@ public class SetGetCompactionThroughputTest extends CQLTester
@Test
public void testMaxValue()
{
assertSetGetValidThroughput(Integer.MAX_VALUE);
assertSetGetValidThroughput(Integer.MAX_VALUE - 1);
}
@Test

View File

@ -55,7 +55,7 @@ public class SetGetEntireSSTableInterDCStreamThroughputTest extends CQLTester
@Test
public void testMaxValue()
{
assertSetGetValidThroughput(Integer.MAX_VALUE, Integer.MAX_VALUE * StreamRateLimiter.BYTES_PER_MEBIBYTE);
assertSetGetValidThroughput(Integer.MAX_VALUE - 1, (Integer.MAX_VALUE - 1) * StreamRateLimiter.BYTES_PER_MEBIBYTE);
}
@Test

View File

@ -55,7 +55,7 @@ public class SetGetEntireSSTableStreamThroughputTest extends CQLTester
@Test
public void testMaxValue()
{
assertSetGetValidThroughput(Integer.MAX_VALUE, Integer.MAX_VALUE * StreamRateLimiter.BYTES_PER_MEBIBYTE);
assertSetGetValidThroughput(Integer.MAX_VALUE - 1, (Integer.MAX_VALUE - 1) * StreamRateLimiter.BYTES_PER_MEBIBYTE);
}
@Test

View File

@ -35,9 +35,10 @@ import static org.assertj.core.api.Assertions.withPrecision;
*/
public class SetGetInterDCStreamThroughputTest extends CQLTester
{
private static final double INTEGER_MAX_VALUE_MEGABITS_IN_MEBIBYTES = DataRateSpec
.megabitsPerSecondInMebibytesPerSecond(Integer.MAX_VALUE)
.toMebibytesPerSecond();
private static final int MAX_INT_CONFIG_VALUE = Integer.MAX_VALUE - 1;
private static final double INTEGER_MAX_VALUE_MEGABITS_IN_MEBIBYTES = DataRateSpec.IntMebibytesPerSecondBound
.megabitsPerSecondInMebibytesPerSecond(MAX_INT_CONFIG_VALUE)
.toMebibytesPerSecond();
@BeforeClass
public static void setup() throws Exception
@ -69,7 +70,7 @@ public class SetGetInterDCStreamThroughputTest extends CQLTester
@Test
public void testMaxValue()
{
assertSetGetValidThroughput(Integer.MAX_VALUE, INTEGER_MAX_VALUE_MEGABITS_IN_MEBIBYTES * StreamRateLimiter.BYTES_PER_MEBIBYTE);
assertSetGetValidThroughput(MAX_INT_CONFIG_VALUE, INTEGER_MAX_VALUE_MEGABITS_IN_MEBIBYTES * StreamRateLimiter.BYTES_PER_MEBIBYTE);
}
@Test

View File

@ -36,9 +36,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
public class SetGetStreamThroughputTest extends CQLTester
{
private static final double INTEGER_MAX_VALUE_MEGABITS_IN_MEBIBYTES = DataRateSpec
.megabitsPerSecondInMebibytesPerSecond(Integer.MAX_VALUE)
.toMebibytesPerSecond();
private static final int MAX_INT_CONFIG_VALUE = Integer.MAX_VALUE - 1;
private static final double INTEGER_MAX_VALUE_MEGABITS_IN_MEBIBYTES = DataRateSpec.IntMebibytesPerSecondBound
.megabitsPerSecondInMebibytesPerSecond(MAX_INT_CONFIG_VALUE)
.toMebibytesPerSecond();
@BeforeClass
public static void setup() throws Exception
@ -70,7 +71,7 @@ public class SetGetStreamThroughputTest extends CQLTester
@Test
public void testMaxValue()
{
assertSetGetValidThroughput(Integer.MAX_VALUE, INTEGER_MAX_VALUE_MEGABITS_IN_MEBIBYTES * StreamRateLimiter.BYTES_PER_MEBIBYTE);
assertSetGetValidThroughput(MAX_INT_CONFIG_VALUE, INTEGER_MAX_VALUE_MEGABITS_IN_MEBIBYTES * StreamRateLimiter.BYTES_PER_MEBIBYTE);
}
@Test

View File

@ -60,6 +60,8 @@ public class RateLimitingTest extends CQLTester
private static final int LARGE_PAYLOAD_THRESHOLD_BYTES = 1000;
private static final int OVERLOAD_PERMITS_PER_SECOND = 1;
private static final long MAX_LONG_CONFIG_VALUE = Long.MAX_VALUE - 1;
@Parameterized.Parameter
public ProtocolVersion version;
@ -99,7 +101,7 @@ public class RateLimitingTest extends CQLTester
}
};
ClientResourceLimits.setGlobalLimit(Long.MAX_VALUE);
ClientResourceLimits.setGlobalLimit(MAX_LONG_CONFIG_VALUE);
}
@Test