From bda88de21f3afeb3afb70f7d44c795eb10212eb7 Mon Sep 17 00:00:00 2001 From: f1v3-dev Date: Tue, 7 Jul 2026 19:17:36 +0900 Subject: [PATCH] FEATURE: Support `long` type expiration time in v2 APIs --- .../java/net/spy/memcached/ArcusClient.java | 79 +++++---- .../net/spy/memcached/OperationFactory.java | 25 ++- .../spy/memcached/collection/Attributes.java | 6 +- .../spy/memcached/collection/BTreeCreate.java | 5 +- .../spy/memcached/collection/BTreeInsert.java | 5 +- .../collection/BTreeInsertAndGet.java | 29 ++-- .../spy/memcached/collection/BTreeUpsert.java | 5 +- .../collection/CollectionAttributes.java | 19 +-- .../collection/CollectionBulkInsert.java | 87 +++++----- .../collection/CollectionCreate.java | 43 ++--- .../collection/CollectionInsert.java | 14 +- .../collection/CollectionPipedInsert.java | 81 +++++----- .../collection/CreateAttributes.java | 124 ++++++++++++++ .../spy/memcached/collection/ListCreate.java | 5 +- .../spy/memcached/collection/ListInsert.java | 4 +- .../spy/memcached/collection/MapCreate.java | 4 +- .../spy/memcached/collection/MapInsert.java | 4 +- .../spy/memcached/collection/MapUpsert.java | 4 +- .../memcached/collection/SetAttributes.java | 44 +++++ .../spy/memcached/collection/SetCreate.java | 4 +- .../spy/memcached/collection/SetInsert.java | 4 +- .../net/spy/memcached/ops/CASOperation.java | 2 +- .../spy/memcached/ops/SetAttrOperation.java | 4 +- .../net/spy/memcached/ops/StoreOperation.java | 2 +- .../net/spy/memcached/ops/TouchOperation.java | 2 +- .../protocol/ascii/AsciiOperationFactory.java | 57 +++++-- .../protocol/ascii/BaseGetOpImpl.java | 7 +- .../ascii/BaseStoreOperationImpl.java | 6 +- .../protocol/ascii/CASOperationImpl.java | 6 +- .../ascii/GetAndTouchOperationImpl.java | 2 +- .../ascii/GetsAndTouchOperationImpl.java | 2 +- .../protocol/ascii/MutatorOperationImpl.java | 4 +- .../protocol/ascii/SetAttrOperationImpl.java | 9 +- .../protocol/ascii/StoreOperationImpl.java | 2 +- .../protocol/ascii/TouchOperationImpl.java | 8 +- .../binary/BinaryOperationFactory.java | 65 ++++++-- .../protocol/binary/OptimizedSetImpl.java | 2 +- .../protocol/binary/StoreOperationImpl.java | 2 +- .../spy/memcached/v2/AsyncArcusCommands.java | 68 ++++---- .../memcached/v2/AsyncArcusCommandsIF.java | 45 +++--- .../v2/attribute/ItemAttributes.java | 123 ++++++++++++++ .../v2/attribute/UpdateAttributes.java | 98 ++++++++++++ .../collection/CreateAttributesTest.java | 38 +++++ .../v2/BTreeAsyncArcusCommandsTest.java | 151 +++++++++--------- .../v2/KVAsyncArcusCommandsTest.java | 6 +- .../v2/ListAsyncArcusCommandsTest.java | 32 ++-- .../v2/MapAsyncArcusCommandsTest.java | 56 +++---- .../v2/SetAsyncArcusCommandsTest.java | 32 ++-- .../v2/attribute/ItemAttributesTest.java | 47 ++++++ .../v2/attribute/UpdateAttributesTest.java | 55 +++++++ .../net/spy/memcached/MultibyteKeyTest.java | 37 +++-- 51 files changed, 1084 insertions(+), 481 deletions(-) create mode 100644 src/main/java/net/spy/memcached/collection/CreateAttributes.java create mode 100644 src/main/java/net/spy/memcached/collection/SetAttributes.java create mode 100644 src/main/java/net/spy/memcached/v2/attribute/ItemAttributes.java create mode 100644 src/main/java/net/spy/memcached/v2/attribute/UpdateAttributes.java create mode 100644 src/test/java/net/spy/memcached/collection/CreateAttributesTest.java create mode 100644 src/test/java/net/spy/memcached/v2/attribute/ItemAttributesTest.java create mode 100644 src/test/java/net/spy/memcached/v2/attribute/UpdateAttributesTest.java diff --git a/src/main/java/net/spy/memcached/ArcusClient.java b/src/main/java/net/spy/memcached/ArcusClient.java index 7316bd0eb..1e1ea0e0c 100644 --- a/src/main/java/net/spy/memcached/ArcusClient.java +++ b/src/main/java/net/spy/memcached/ArcusClient.java @@ -45,6 +45,7 @@ import java.util.jar.Manifest; import net.spy.memcached.collection.Attributes; +import net.spy.memcached.collection.CreateAttributes; import net.spy.memcached.collection.BKeyObject; import net.spy.memcached.collection.BTreeCount; import net.spy.memcached.collection.BTreeCreate; @@ -1073,10 +1074,8 @@ public CollectionFuture asyncBopCreate(String key, ElementValueType valueType, CollectionAttributes attributes) { int flag = TranscoderUtils.examineFlags(valueType); - boolean noreply = false; - CollectionCreate bTreeCreate = new BTreeCreate(flag, - attributes.getExpireTime(), attributes.getMaxCount(), - attributes.getOverflowAction(), attributes.getReadable(), noreply); + CreateAttributes createAttributes = CreateAttributes.of(attributes); + CollectionCreate bTreeCreate = new BTreeCreate(flag, createAttributes, false); return asyncCollectionCreate(key, bTreeCreate); } @@ -1085,10 +1084,8 @@ public CollectionFuture asyncMopCreate(String key, ElementValueType type, CollectionAttributes attributes) { int flag = TranscoderUtils.examineFlags(type); - boolean noreply = false; - CollectionCreate mapCreate = new MapCreate(flag, - attributes.getExpireTime(), attributes.getMaxCount(), - attributes.getReadable(), noreply); + CreateAttributes createAttributes = CreateAttributes.of(attributes); + CollectionCreate mapCreate = new MapCreate(flag, createAttributes, false); return asyncCollectionCreate(key, mapCreate); } @@ -1097,10 +1094,8 @@ public CollectionFuture asyncSopCreate(String key, ElementValueType type, CollectionAttributes attributes) { int flag = TranscoderUtils.examineFlags(type); - boolean noreply = false; - CollectionCreate setCreate = new SetCreate(flag, - attributes.getExpireTime(), attributes.getMaxCount(), - attributes.getReadable(), noreply); + CreateAttributes createAttributes = CreateAttributes.of(attributes); + CollectionCreate setCreate = new SetCreate(flag, createAttributes, false); return asyncCollectionCreate(key, setCreate); } @@ -1109,10 +1104,8 @@ public CollectionFuture asyncLopCreate(String key, ElementValueType type, CollectionAttributes attributes) { int flag = TranscoderUtils.examineFlags(type); - boolean noreply = false; - CollectionCreate listCreate = new ListCreate(flag, - attributes.getExpireTime(), attributes.getMaxCount(), - attributes.getOverflowAction(), attributes.getReadable(), noreply); + CreateAttributes createAttributes = CreateAttributes.of(attributes); + CollectionCreate listCreate = new ListCreate(flag, createAttributes, false); return asyncCollectionCreate(key, listCreate); } @@ -1549,7 +1542,7 @@ public CollectionFuture asyncBopInsert(String key, long bkey, CollectionAttributes attributesForCreate, Transcoder tc) { KeyValidator.validateBKey(bkey); - BTreeInsert bTreeInsert = new BTreeInsert<>(value, eFlag, null, attributesForCreate); + BTreeInsert bTreeInsert = new BTreeInsert<>(value, eFlag, null, CreateAttributes.of(attributesForCreate)); return asyncCollectionInsert(key, String.valueOf(bkey), bTreeInsert, tc); } @@ -1559,7 +1552,7 @@ public CollectionFuture asyncMopInsert(String key, String mkey, CollectionAttributes attributesForCreate, Transcoder tc) { keyValidator.validateMKey(mkey); - MapInsert mapInsert = new MapInsert<>(value, null, attributesForCreate); + MapInsert mapInsert = new MapInsert<>(value, null, CreateAttributes.of(attributesForCreate)); return asyncCollectionInsert(key, mkey, mapInsert, tc); } @@ -1568,7 +1561,7 @@ public CollectionFuture asyncLopInsert(String key, int index, T value, CollectionAttributes attributesForCreate, Transcoder tc) { - ListInsert listInsert = new ListInsert<>(value, null, attributesForCreate); + ListInsert listInsert = new ListInsert<>(value, null, CreateAttributes.of(attributesForCreate)); return asyncCollectionInsert(key, String.valueOf(index), listInsert, tc); } @@ -1576,7 +1569,7 @@ public CollectionFuture asyncLopInsert(String key, int index, public CollectionFuture asyncSopInsert(String key, T value, CollectionAttributes attributesForCreate, Transcoder tc) { - SetInsert setInsert = new SetInsert<>(value, null, attributesForCreate); + SetInsert setInsert = new SetInsert<>(value, null, CreateAttributes.of(attributesForCreate)); return asyncCollectionInsert(key, "", setInsert, tc); } @@ -1628,11 +1621,11 @@ public CollectionFuture> asyncBopPip List> insertList = new ArrayList<>(); if (elements.size() <= MAX_PIPED_ITEM_COUNT) { - insertList.add(new BTreePipedInsert<>(key, elements, attributesForCreate, tc)); + insertList.add(new BTreePipedInsert<>(key, elements, CreateAttributes.of(attributesForCreate), tc)); } else { PartitionedMap list = new PartitionedMap<>(elements, MAX_PIPED_ITEM_COUNT); for (Map elementMap : list) { - insertList.add(new BTreePipedInsert<>(key, elementMap, attributesForCreate, tc)); + insertList.add(new BTreePipedInsert<>(key, elementMap, CreateAttributes.of(attributesForCreate), tc)); } } return syncCollectionPipedInsert(key, insertList); @@ -1651,11 +1644,11 @@ public CollectionFuture> asyncBopPip List> insertList = new ArrayList<>(); if (elements.size() <= MAX_PIPED_ITEM_COUNT) { - insertList.add(new ByteArraysBTreePipedInsert<>(key, elements, attributesForCreate, tc)); + insertList.add(new ByteArraysBTreePipedInsert<>(key, elements, CreateAttributes.of(attributesForCreate), tc)); } else { PartitionedList> list = new PartitionedList<>(elements, MAX_PIPED_ITEM_COUNT); for (List> elementList : list) { - insertList.add(new ByteArraysBTreePipedInsert<>(key, elementList, attributesForCreate, tc)); + insertList.add(new ByteArraysBTreePipedInsert<>(key, elementList, CreateAttributes.of(attributesForCreate), tc)); } } return syncCollectionPipedInsert(key, insertList); @@ -1676,11 +1669,11 @@ public CollectionFuture> asyncMopPip List> insertList = new ArrayList<>(); if (elements.size() <= MAX_PIPED_ITEM_COUNT) { - insertList.add(new MapPipedInsert<>(key, elements, attributesForCreate, tc)); + insertList.add(new MapPipedInsert<>(key, elements, CreateAttributes.of(attributesForCreate), tc)); } else { PartitionedMap list = new PartitionedMap<>(elements, MAX_PIPED_ITEM_COUNT); for (Map elementMap : list) { - insertList.add(new MapPipedInsert<>(key, elementMap, attributesForCreate, tc)); + insertList.add(new MapPipedInsert<>(key, elementMap, CreateAttributes.of(attributesForCreate), tc)); } } return syncCollectionPipedInsert(key, insertList); @@ -1699,11 +1692,11 @@ public CollectionFuture> asyncLopPip List> insertList = new ArrayList<>(); if (valueList.size() <= MAX_PIPED_ITEM_COUNT) { - insertList.add(new ListPipedInsert<>(key, index, valueList, attributesForCreate, tc)); + insertList.add(new ListPipedInsert<>(key, index, valueList, CreateAttributes.of(attributesForCreate), tc)); } else { PartitionedList list = new PartitionedList<>(valueList, MAX_PIPED_ITEM_COUNT); for (List elementList : list) { - insertList.add(new ListPipedInsert<>(key, index, elementList, attributesForCreate, tc)); + insertList.add(new ListPipedInsert<>(key, index, elementList, CreateAttributes.of(attributesForCreate), tc)); if (index >= 0) { index += elementList.size(); } @@ -1725,11 +1718,11 @@ public CollectionFuture> asyncSopPip List> insertList = new ArrayList<>(); if (valueList.size() <= MAX_PIPED_ITEM_COUNT) { - insertList.add(new SetPipedInsert<>(key, valueList, attributesForCreate, tc)); + insertList.add(new SetPipedInsert<>(key, valueList, CreateAttributes.of(attributesForCreate), tc)); } else { PartitionedList list = new PartitionedList<>(valueList, MAX_PIPED_ITEM_COUNT); for (List elementList : list) { - insertList.add(new SetPipedInsert<>(key, elementList, attributesForCreate, tc)); + insertList.add(new SetPipedInsert<>(key, elementList, CreateAttributes.of(attributesForCreate), tc)); } } return syncCollectionPipedInsert(key, insertList); @@ -1930,7 +1923,7 @@ public CollectionFuture asyncBopUpsert(String key, long bkey, Transcoder tc) { KeyValidator.validateBKey(bkey); - BTreeUpsert bTreeUpsert = new BTreeUpsert<>(value, elementFlag, null, attributesForCreate); + BTreeUpsert bTreeUpsert = new BTreeUpsert<>(value, elementFlag, null, CreateAttributes.of(attributesForCreate)); return asyncCollectionInsert(key, String.valueOf(bkey), bTreeUpsert, tc); } @@ -1946,7 +1939,7 @@ public CollectionFuture asyncMopUpsert(String key, String mkey, T v CollectionAttributes attributesForCreate, Transcoder tc) { keyValidator.validateMKey(mkey); - MapUpsert mapUpsert = new MapUpsert<>(value, attributesForCreate); + MapUpsert mapUpsert = new MapUpsert<>(value, CreateAttributes.of(attributesForCreate)); return asyncCollectionInsert(key, mkey, mapUpsert, tc); } @@ -2171,7 +2164,7 @@ public CollectionFuture asyncBopInsert(String key, CollectionAttributes attributesForCreate, Transcoder tc) { KeyValidator.validateBKey(bkey); - BTreeInsert bTreeInsert = new BTreeInsert<>(value, eFlag, null, attributesForCreate); + BTreeInsert bTreeInsert = new BTreeInsert<>(value, eFlag, null, CreateAttributes.of(attributesForCreate)); return asyncCollectionInsert(key, BTreeUtil.toHex(bkey), bTreeInsert, tc); } @@ -2509,7 +2502,7 @@ public BTreeStoreAndGetFuture asyncBopInsertAndGetTrimmed( String key, long bkey, byte[] eFlag, E value, CollectionAttributes attributesForCreate, Transcoder transcoder) { BTreeInsertAndGet insertAndGet - = new BTreeInsertAndGet<>(bkey, eFlag, value, false, attributesForCreate); + = new BTreeInsertAndGet<>(bkey, eFlag, value, false, CreateAttributes.of(attributesForCreate)); return asyncBTreeInsertAndGet(key, insertAndGet, transcoder); } @@ -2525,7 +2518,7 @@ public BTreeStoreAndGetFuture asyncBopInsertAndGetTrimmed( String key, byte[] bkey, byte[] eFlag, E value, CollectionAttributes attributesForCreate, Transcoder transcoder) { BTreeInsertAndGet insertAndGet - = new BTreeInsertAndGet<>(bkey, eFlag, value, false, attributesForCreate); + = new BTreeInsertAndGet<>(bkey, eFlag, value, false, CreateAttributes.of(attributesForCreate)); return asyncBTreeInsertAndGet(key, insertAndGet, transcoder); } @@ -2541,7 +2534,7 @@ public BTreeStoreAndGetFuture asyncBopUpsertAndGetTrimmed( String key, long bkey, byte[] eFlag, E value, CollectionAttributes attributesForCreate, Transcoder transcoder) { BTreeInsertAndGet insertAndGet - = new BTreeInsertAndGet<>(bkey, eFlag, value, true, attributesForCreate); + = new BTreeInsertAndGet<>(bkey, eFlag, value, true, CreateAttributes.of(attributesForCreate)); return asyncBTreeInsertAndGet(key, insertAndGet, transcoder); } @@ -2557,7 +2550,7 @@ public BTreeStoreAndGetFuture asyncBopUpsertAndGetTrimmed( String key, byte[] bkey, byte[] eFlag, E value, CollectionAttributes attributesForCreate, Transcoder transcoder) { BTreeInsertAndGet insertAndGet - = new BTreeInsertAndGet<>(bkey, eFlag, value, true, attributesForCreate); + = new BTreeInsertAndGet<>(bkey, eFlag, value, true, CreateAttributes.of(attributesForCreate)); return asyncBTreeInsertAndGet(key, insertAndGet, transcoder); } @@ -2639,7 +2632,7 @@ public CollectionFuture asyncBopUpsert(String key, CollectionAttributes attributesForCreate, Transcoder tc) { KeyValidator.validateBKey(bkey); - BTreeUpsert bTreeUpsert = new BTreeUpsert<>(value, elementFlag, null, attributesForCreate); + BTreeUpsert bTreeUpsert = new BTreeUpsert<>(value, elementFlag, null, CreateAttributes.of(attributesForCreate)); return asyncCollectionInsert(key, BTreeUtil.toHex(bkey), bTreeUpsert, tc); } @@ -2818,7 +2811,7 @@ public Future> asyncBopInsertBulk( insertList.add(new CollectionBulkInsert.BTreeBulkInsert<>( entry.getKey(), entry.getValue(), String.valueOf(bkey), BTreeUtil.toHex(eFlag), - insertValue, attributesForCreate)); + insertValue, CreateAttributes.of(attributesForCreate))); } return asyncCollectionInsertBulk2(insertList); @@ -2851,7 +2844,7 @@ public Future> asyncBopInsertBulk( insertList.add(new CollectionBulkInsert.BTreeBulkInsert<>( entry.getKey(), entry.getValue(), BTreeUtil.toHex(bkey), BTreeUtil.toHex(eFlag), - insertValue, attributesForCreate)); + insertValue, CreateAttributes.of(attributesForCreate))); } return asyncCollectionInsertBulk2(insertList); @@ -2883,7 +2876,7 @@ public Future> asyncMopInsertBulk( for (Entry> entry : arrangedKey) { insertList.add(new CollectionBulkInsert.MapBulkInsert<>( entry.getKey(), entry.getValue(), - mkey, insertValue, attributesForCreate)); + mkey, insertValue, CreateAttributes.of(attributesForCreate))); } return asyncCollectionInsertBulk2(insertList); @@ -2913,7 +2906,7 @@ public Future> asyncSopInsertBulk( for (Entry> entry : arrangedKey) { insertList.add(new CollectionBulkInsert.SetBulkInsert<>( entry.getKey(), entry.getValue(), - insertValue, attributesForCreate)); + insertValue, CreateAttributes.of(attributesForCreate))); } return asyncCollectionInsertBulk2(insertList); @@ -2943,7 +2936,7 @@ public Future> asyncLopInsertBulk( for (Entry> entry : arrangedKey) { insertList.add(new CollectionBulkInsert.ListBulkInsert<>( entry.getKey(), entry.getValue(), - index, insertValue, attributesForCreate)); + index, insertValue, CreateAttributes.of(attributesForCreate))); } return asyncCollectionInsertBulk2(insertList); diff --git a/src/main/java/net/spy/memcached/OperationFactory.java b/src/main/java/net/spy/memcached/OperationFactory.java index 3abbd4032..22c11cb0e 100644 --- a/src/main/java/net/spy/memcached/OperationFactory.java +++ b/src/main/java/net/spy/memcached/OperationFactory.java @@ -21,7 +21,6 @@ import javax.security.sasl.SaslClient; -import net.spy.memcached.collection.Attributes; import net.spy.memcached.collection.BTreeFindPosition; import net.spy.memcached.collection.BTreeFindPositionWithGet; import net.spy.memcached.collection.BTreeGetBulk; @@ -39,6 +38,7 @@ import net.spy.memcached.collection.CollectionPipedInsert; import net.spy.memcached.collection.CollectionPipedUpdate; import net.spy.memcached.collection.CollectionUpdate; +import net.spy.memcached.collection.SetAttributes; import net.spy.memcached.collection.SetPipedExist; import net.spy.memcached.ops.BTreeFindPositionOperation; import net.spy.memcached.ops.BTreeFindPositionWithGetOperation; @@ -156,27 +156,27 @@ public interface OperationFactory { * Get the key and resets its timeout. * * @param key the key to get a value for and reset its timeout - * @param expiration the new expiration for the key + * @param exp the new expiration for the key * @param cb the callback that will contain the result * @return a new GetAndTouchOperation */ - GetOperation getAndTouch(String key, int expiration, GetOperation.Callback cb); + GetOperation getAndTouch(String key, long exp, GetOperation.Callback cb); /** * Gets (with CAS support) the key and resets its timeout. * * @param key the key to get a value for and reset its timeout - * @param expiration the new expiration for the key + * @param exp the new expiration for the key * @param cb the callback that will contain the result * @return a new GetsAndTouchOperation */ - GetsOperation getsAndTouch(String key, int expiration, GetsOperation.Callback cb); + GetsOperation getsAndTouch(String key, long exp, GetsOperation.Callback cb); /** * Create a mutator operation. * * @param m the mutator type - * @param key the mutatee key + * @param key the mutate key * @param by the amount to increment or decrement * @param def the default value * @param exp expiration in case we need to default (0 if no default) @@ -184,7 +184,7 @@ public interface OperationFactory { * @return the new mutator operation */ MutatorOperation mutate(Mutator m, String key, int by, - long def, int exp, OperationCallback cb); + long def, long exp, OperationCallback cb); /** * Get a new StatsOperation. @@ -206,18 +206,18 @@ MutatorOperation mutate(Mutator m, String key, int by, * @param cb the status callback * @return the new store operation */ - StoreOperation store(StoreType storeType, String key, int flags, int exp, + StoreOperation store(StoreType storeType, String key, int flags, long exp, byte[] data, OperationCallback cb); /** * Create a touch operation. * * @param key the key to touch - * @param expiration the new expiration time + * @param exp the new expiration time * @param cb the status callback * @return the new touch operation */ - TouchOperation touch(String key, int expiration, OperationCallback cb); + TouchOperation touch(String key, long exp, OperationCallback cb); /** * Get a concatenation operation. @@ -244,7 +244,7 @@ ConcatenationOperation cat(ConcatenationType catType, long casId, * @return the new store operation */ CASOperation cas(StoreType t, String key, long casId, int flags, - int exp, byte[] data, OperationCallback cb); + long exp, byte[] data, OperationCallback cb); /** * Create a new version operation. @@ -274,8 +274,7 @@ CASOperation cas(StoreType t, String key, long casId, int flags, * @param cb the status callback * @return a new SetAttrOperation */ - SetAttrOperation setAttr(String key, Attributes attrs, - OperationCallback cb); + SetAttrOperation setAttr(String key, SetAttributes attrs, OperationCallback cb); /** * Get item attributes diff --git a/src/main/java/net/spy/memcached/collection/Attributes.java b/src/main/java/net/spy/memcached/collection/Attributes.java index ac81ba9f8..f0692b611 100644 --- a/src/main/java/net/spy/memcached/collection/Attributes.java +++ b/src/main/java/net/spy/memcached/collection/Attributes.java @@ -18,7 +18,7 @@ import net.spy.memcached.compat.SpyObject; -public class Attributes extends SpyObject { +public class Attributes extends SpyObject implements SetAttributes { public static final Integer DEFAULT_FLAGS = 0; public static final Integer DEFAULT_EXPIRETIME = 0; @@ -35,7 +35,8 @@ public Attributes(Integer expireTime) { this.expireTime = expireTime; } - protected String stringify() { + @Override + public String stringify() { if (str != null) { return str; } @@ -64,6 +65,7 @@ public String toString() { return (str == null) ? stringify() : str; } + @Override public int getLength() { return (str == null) ? stringify().length() : str.length(); } diff --git a/src/main/java/net/spy/memcached/collection/BTreeCreate.java b/src/main/java/net/spy/memcached/collection/BTreeCreate.java index 1e883aa1c..c4eee7696 100644 --- a/src/main/java/net/spy/memcached/collection/BTreeCreate.java +++ b/src/main/java/net/spy/memcached/collection/BTreeCreate.java @@ -20,9 +20,8 @@ public class BTreeCreate extends CollectionCreate { private static final String COMMAND = "bop create"; - public BTreeCreate(int flags, Integer expTime, Long maxCount, - CollectionOverflowAction overflowAction, Boolean readable, boolean noreply) { - super(CollectionType.btree, flags, expTime, maxCount, overflowAction, readable, noreply); + public BTreeCreate(int flags, CreateAttributes option, boolean noreply) { + super(CollectionType.btree, flags, option, noreply); } public String getCommand() { diff --git a/src/main/java/net/spy/memcached/collection/BTreeInsert.java b/src/main/java/net/spy/memcached/collection/BTreeInsert.java index 471cf82cd..f7c37c6c4 100644 --- a/src/main/java/net/spy/memcached/collection/BTreeInsert.java +++ b/src/main/java/net/spy/memcached/collection/BTreeInsert.java @@ -20,8 +20,9 @@ public class BTreeInsert extends CollectionInsert { private static final String COMMAND = "bop insert"; - public BTreeInsert(T value, byte[] eFlag, RequestMode requestMode, CollectionAttributes attr) { - super(CollectionType.btree, value, eFlag, requestMode, attr); + public BTreeInsert(T value, byte[] eFlag, RequestMode requestMode, + CreateAttributes createAttributes) { + super(CollectionType.btree, value, eFlag, requestMode, createAttributes); } public String getCommand() { diff --git a/src/main/java/net/spy/memcached/collection/BTreeInsertAndGet.java b/src/main/java/net/spy/memcached/collection/BTreeInsertAndGet.java index 6891b36b5..7382df7a4 100644 --- a/src/main/java/net/spy/memcached/collection/BTreeInsertAndGet.java +++ b/src/main/java/net/spy/memcached/collection/BTreeInsertAndGet.java @@ -40,27 +40,28 @@ public class BTreeInsertAndGet extends CollectionGet { private BKeyObject bKey; public BTreeInsertAndGet(long bkey, byte[] eFlag, T value, boolean updateIfExist, - CollectionAttributes attributesForCreate) { - if (updateIfExist) { - this.collection = new BTreeUpsert<>(value, eFlag, RequestMode.GET_TRIM, attributesForCreate); - } else { - this.collection = new BTreeInsert<>(value, eFlag, RequestMode.GET_TRIM, attributesForCreate); - } - this.updateIfExist = updateIfExist; - this.bKey = new BKeyObject(bkey); - this.eHeadCount = 2; - this.eFlagIndex = 1; + CreateAttributes createAttributes) { + this(new BKeyObject(bkey), eFlag, value, updateIfExist, createAttributes); } public BTreeInsertAndGet(byte[] bkey, byte[] eFlag, T value, boolean updateIfExist, - CollectionAttributes attributesForCreate) { + CreateAttributes createAttributes) { + this(new BKeyObject(bkey), eFlag, value, updateIfExist, createAttributes); + } + + private BTreeInsertAndGet(BKeyObject bKey, byte[] eFlag, T value, boolean updateIfExist, + CreateAttributes createOptionForCreate) { if (updateIfExist) { - this.collection = new BTreeUpsert<>(value, eFlag, RequestMode.GET_TRIM, attributesForCreate); + this.collection = new BTreeUpsert<>( + value, eFlag, RequestMode.GET_TRIM, createOptionForCreate + ); } else { - this.collection = new BTreeInsert<>(value, eFlag, RequestMode.GET_TRIM, attributesForCreate); + this.collection = new BTreeInsert<>( + value, eFlag, RequestMode.GET_TRIM, createOptionForCreate + ); } this.updateIfExist = updateIfExist; - this.bKey = new BKeyObject(bkey); + this.bKey = bKey; this.eHeadCount = 2; this.eFlagIndex = 1; } diff --git a/src/main/java/net/spy/memcached/collection/BTreeUpsert.java b/src/main/java/net/spy/memcached/collection/BTreeUpsert.java index c4cfcaf95..e7810d16a 100644 --- a/src/main/java/net/spy/memcached/collection/BTreeUpsert.java +++ b/src/main/java/net/spy/memcached/collection/BTreeUpsert.java @@ -20,8 +20,9 @@ public class BTreeUpsert extends CollectionInsert { private static final String COMMAND = "bop upsert"; - public BTreeUpsert(T value, byte[] eFlag, RequestMode requestMode, CollectionAttributes attr) { - super(CollectionType.btree, value, eFlag, requestMode, attr); + public BTreeUpsert(T value, byte[] eFlag, RequestMode requestMode, + CreateAttributes createAttributes) { + super(CollectionType.btree, value, eFlag, requestMode, createAttributes); } public String getCommand() { diff --git a/src/main/java/net/spy/memcached/collection/CollectionAttributes.java b/src/main/java/net/spy/memcached/collection/CollectionAttributes.java index c59635b62..782cf1420 100644 --- a/src/main/java/net/spy/memcached/collection/CollectionAttributes.java +++ b/src/main/java/net/spy/memcached/collection/CollectionAttributes.java @@ -48,7 +48,8 @@ public CollectionAttributes(Integer expireTime, this.overflowAction = overflowAction; } - protected String stringify() { + @Override + public String stringify() { StringBuilder b = new StringBuilder(); if (flags != null) { @@ -81,14 +82,11 @@ protected String stringify() { } @Override - public String toString() { - return (stringCache == null) ? stringify() : stringCache; - } - public int getLength() { return (stringCache == null) ? stringify().length() : stringCache.length(); } + @Override public void setAttribute(String attribute) { String[] splited = attribute.split("="); assert splited.length == 2 : "An attribute should be given in \"name=value\" format."; @@ -97,13 +95,7 @@ public void setAttribute(String attribute) { String value = splited[1]; try { - if ("flags".equals(name)) { - flags = Integer.parseInt(value); - } else if ("expiretime".equals(name)) { - expireTime = Integer.parseInt(value); - } else if ("type".equals(name)) { - type = CollectionType.find(value); - } else if ("count".equals(name)) { + if ("count".equals(name)) { count = Long.parseLong(value); } else if ("maxcount".equals(name)) { maxCount = Long.parseLong(value); @@ -138,6 +130,9 @@ public void setAttribute(String attribute) { } } else if ("trimmed".equals(name)) { trimmed = Long.parseLong(value); + } else { + // flags, expiretime, type are handled by the base class. + super.setAttribute(attribute); } } catch (Exception e) { getLogger().info(e, e); diff --git a/src/main/java/net/spy/memcached/collection/CollectionBulkInsert.java b/src/main/java/net/spy/memcached/collection/CollectionBulkInsert.java index b2b2ead49..ec16e9e81 100644 --- a/src/main/java/net/spy/memcached/collection/CollectionBulkInsert.java +++ b/src/main/java/net/spy/memcached/collection/CollectionBulkInsert.java @@ -30,15 +30,15 @@ public abstract class CollectionBulkInsert extends CollectionPipe { protected final MemcachedNode node; protected final List keyList; protected final CachedData cachedData; - protected final CollectionAttributes attribute; + protected final CreateAttributes createAttributes; protected CollectionBulkInsert(MemcachedNode node, List keyList, - CachedData cachedData, CollectionAttributes attribute) { + CachedData cachedData, CreateAttributes createAttributes) { super(keyList.size()); this.node = node; this.keyList = keyList; this.cachedData = cachedData; - this.attribute = attribute; + this.createAttributes = createAttributes; } public String getKey(int index) { @@ -67,10 +67,13 @@ public static class BTreeBulkInsert extends CollectionBulkInsert { private final String eflag; public BTreeBulkInsert(MemcachedNode node, List keyList, String bkey, - String eflag, CachedData cachedData, CollectionAttributes attr) { - super(node, keyList, cachedData, attr); - if (attr != null) { /* item creation option */ - CollectionCreate.checkOverflowAction(CollectionType.btree, attr.getOverflowAction()); + String eflag, CachedData cachedData, + CreateAttributes createAttributes) { + super(node, keyList, cachedData, createAttributes); + if (createAttributes != null) { /* item creation option */ + CollectionCreate.checkOverflowAction( + CollectionType.btree, createAttributes.getOverflowAction() + ); } this.bkey = bkey; this.eflag = eflag; @@ -81,8 +84,8 @@ public ByteBuffer getAsciiCommand() { // estimate the buffer capacity int eachExtraSize = bkey.length() - + ((eflag != null) ? eflag.length() : 0) - + cachedData.getData().length + 128; + + ((eflag != null) ? eflag.length() : 0) + + cachedData.getData().length + 128; for (String eachKey : keyList) { capacity += KeyUtil.getKeyBytes(eachKey).length; } @@ -94,12 +97,12 @@ public ByteBuffer getAsciiCommand() { // create ascii operation string int kSize = this.keyList.size(); byte[] value = cachedData.getData(); - String createOption = attribute != null ? - CollectionCreate.makeCreateClause(attribute, cachedData.getFlags()) : ""; + String createClause = createAttributes != null ? + CollectionCreate.makeCreateClause(createAttributes, cachedData.getFlags()) : ""; for (int i = this.nextOpIndex; i < kSize; i++) { String key = keyList.get(i); setArguments(bb, COMMAND, key, bkey, (eflag != null) ? eflag : "", value.length, - createOption, (i < kSize - 1) ? PIPE : ""); + createClause, (i < kSize - 1) ? PIPE : ""); bb.put(value); bb.put(CRLF); } @@ -113,7 +116,7 @@ public ByteBuffer getAsciiCommand() { @Override public CollectionBulkInsert clone(MemcachedNode node, List keyList) { - return new BTreeBulkInsert<>(node, keyList, bkey, eflag, cachedData, attribute); + return new BTreeBulkInsert<>(node, keyList, bkey, eflag, cachedData, createAttributes); } } @@ -123,10 +126,12 @@ public static class MapBulkInsert extends CollectionBulkInsert { private final String mkey; public MapBulkInsert(MemcachedNode node, List keyList, String mkey, - CachedData cachedData, CollectionAttributes attr) { - super(node, keyList, cachedData, attr); - if (attr != null) { /* item creation option */ - CollectionCreate.checkOverflowAction(CollectionType.map, attr.getOverflowAction()); + CachedData cachedData, CreateAttributes createAttributes) { + super(node, keyList, cachedData, createAttributes); + if (createAttributes != null) { /* item creation option */ + CollectionCreate.checkOverflowAction( + CollectionType.map, createAttributes.getOverflowAction() + ); } this.mkey = mkey; } @@ -136,7 +141,7 @@ public ByteBuffer getAsciiCommand() { // estimate the buffer capacity int eachExtraSize = KeyUtil.getKeyBytes(mkey).length - + cachedData.getData().length + 128; + + cachedData.getData().length + 128; for (String eachKey : keyList) { capacity += KeyUtil.getKeyBytes(eachKey).length; } @@ -148,12 +153,12 @@ public ByteBuffer getAsciiCommand() { // create ascii operation string int kSize = this.keyList.size(); byte[] value = cachedData.getData(); - String createOption = attribute != null ? - CollectionCreate.makeCreateClause(attribute, cachedData.getFlags()) : ""; + String createClause = createAttributes != null ? + CollectionCreate.makeCreateClause(createAttributes, cachedData.getFlags()) : ""; for (int i = this.nextOpIndex; i < kSize; i++) { String key = keyList.get(i); setArguments(bb, COMMAND, key, mkey, value.length, - createOption, (i < kSize - 1) ? PIPE : ""); + createClause, (i < kSize - 1) ? PIPE : ""); bb.put(value); bb.put(CRLF); } @@ -167,7 +172,7 @@ public ByteBuffer getAsciiCommand() { @Override public CollectionBulkInsert clone(MemcachedNode node, List keyList) { - return new MapBulkInsert<>(node, keyList, mkey, cachedData, attribute); + return new MapBulkInsert<>(node, keyList, mkey, cachedData, createAttributes); } } @@ -176,10 +181,12 @@ public static class SetBulkInsert extends CollectionBulkInsert { private static final String COMMAND = "sop insert"; public SetBulkInsert(MemcachedNode node, List keyList, - CachedData cachedData, CollectionAttributes attr) { - super(node, keyList, cachedData, attr); - if (attr != null) { /* item creation option */ - CollectionCreate.checkOverflowAction(CollectionType.set, attr.getOverflowAction()); + CachedData cachedData, CreateAttributes createAttributes) { + super(node, keyList, cachedData, createAttributes); + if (createAttributes != null) { /* item creation option */ + CollectionCreate.checkOverflowAction( + CollectionType.set, createAttributes.getOverflowAction() + ); } } @@ -199,12 +206,12 @@ public ByteBuffer getAsciiCommand() { // create ascii operation string int kSize = this.keyList.size(); byte[] value = cachedData.getData(); - String createOption = attribute != null ? - CollectionCreate.makeCreateClause(attribute, cachedData.getFlags()) : ""; + String createClause = createAttributes != null ? + CollectionCreate.makeCreateClause(createAttributes, cachedData.getFlags()) : ""; for (int i = this.nextOpIndex; i < kSize; i++) { String key = keyList.get(i); setArguments(bb, COMMAND, key, value.length, - createOption, (i < kSize - 1) ? PIPE : ""); + createClause, (i < kSize - 1) ? PIPE : ""); bb.put(value); bb.put(CRLF); } @@ -217,7 +224,7 @@ public ByteBuffer getAsciiCommand() { @Override public CollectionBulkInsert clone(MemcachedNode node, List keyList) { - return new SetBulkInsert<>(node, keyList, cachedData, attribute); + return new SetBulkInsert<>(node, keyList, cachedData, createAttributes); } } @@ -227,10 +234,12 @@ public static class ListBulkInsert extends CollectionBulkInsert { private final int index; public ListBulkInsert(MemcachedNode node, List keyList, int index, - CachedData cachedData, CollectionAttributes attr) { - super(node, keyList, cachedData, attr); - if (attr != null) { /* item creation option */ - CollectionCreate.checkOverflowAction(CollectionType.list, attr.getOverflowAction()); + CachedData cachedData, CreateAttributes createAttributes) { + super(node, keyList, cachedData, createAttributes); + if (createAttributes != null) { /* item creation option */ + CollectionCreate.checkOverflowAction( + CollectionType.list, createAttributes.getOverflowAction() + ); } this.index = index; } @@ -240,7 +249,7 @@ public ByteBuffer getAsciiCommand() { // estimate the buffer capacity int eachExtraSize = String.valueOf(index).length() - + cachedData.getData().length + 128; + + cachedData.getData().length + 128; for (String eachKey : keyList) { capacity += KeyUtil.getKeyBytes(eachKey).length; } @@ -252,12 +261,12 @@ public ByteBuffer getAsciiCommand() { // create ascii operation string int kSize = keyList.size(); byte[] value = cachedData.getData(); - String createOption = attribute != null ? - CollectionCreate.makeCreateClause(attribute, cachedData.getFlags()) : ""; + String createClause = createAttributes != null ? + CollectionCreate.makeCreateClause(createAttributes, cachedData.getFlags()) : ""; for (int i = this.nextOpIndex; i < kSize; i++) { String key = this.keyList.get(i); setArguments(bb, COMMAND, key, index, value.length, - createOption, (i < kSize - 1) ? PIPE : ""); + createClause, (i < kSize - 1) ? PIPE : ""); bb.put(value); bb.put(CRLF); } @@ -271,7 +280,7 @@ public ByteBuffer getAsciiCommand() { @Override public CollectionBulkInsert clone(MemcachedNode node, List keyList) { - return new ListBulkInsert<>(node, keyList, index, cachedData, attribute); + return new ListBulkInsert<>(node, keyList, index, cachedData, createAttributes); } } } diff --git a/src/main/java/net/spy/memcached/collection/CollectionCreate.java b/src/main/java/net/spy/memcached/collection/CollectionCreate.java index c28a1063c..c6e127aa8 100644 --- a/src/main/java/net/spy/memcached/collection/CollectionCreate.java +++ b/src/main/java/net/spy/memcached/collection/CollectionCreate.java @@ -18,23 +18,16 @@ public abstract class CollectionCreate { protected int flags; - protected int expTime; - protected long maxCount; - protected CollectionOverflowAction overflowAction; - protected Boolean readable; + protected CreateAttributes attributes; protected boolean noreply; protected String str; - protected CollectionCreate(CollectionType type, int flags, Integer expTime, Long maxCount, - CollectionOverflowAction overflowAction, Boolean readable, - boolean noreply) { - checkOverflowAction(type, overflowAction); + protected CollectionCreate(CollectionType type, int flags, + CreateAttributes attr, boolean noreply) { + checkOverflowAction(type, attr.getOverflowAction()); this.flags = flags; - this.expTime = (null == expTime) ? CollectionAttributes.DEFAULT_EXPIRETIME : expTime; - this.maxCount = (null == maxCount) ? CollectionAttributes.DEFAULT_MAXCOUNT : maxCount; - this.overflowAction = overflowAction; - this.readable = readable; + this.attributes = attr; this.noreply = noreply; } @@ -46,14 +39,14 @@ public String stringify() { StringBuilder b = new StringBuilder(); b.append(flags); - b.append(' ').append(expTime); - b.append(' ').append(maxCount); + b.append(' ').append(attributes.getExpireTime()); + b.append(' ').append(attributes.getMaxCount()); - if (null != overflowAction) { - b.append(' ').append(overflowAction); + if (null != attributes.getOverflowAction()) { + b.append(' ').append(attributes.getOverflowAction()); } - if (null != readable && !readable) { + if (!attributes.getReadable()) { b.append(' ').append("unreadable"); } @@ -65,20 +58,18 @@ public String stringify() { return str; } - public static String makeCreateClause(CollectionAttributes attribute, int flags) { - if (attribute == null) { + public static String makeCreateClause(CreateAttributes attributes, int flags) { + if (attributes == null) { return null; } StringBuilder b = new StringBuilder(); b.append("create ").append(flags) - .append(" ").append((attribute.getExpireTime() == null) ? - CollectionAttributes.DEFAULT_EXPIRETIME : attribute.getExpireTime()) - .append(" ").append((attribute.getMaxCount() == null) ? - CollectionAttributes.DEFAULT_MAXCOUNT : attribute.getMaxCount()); - if (attribute.getOverflowAction() != null) { - b.append(" ").append(attribute.getOverflowAction()); + .append(" ").append(attributes.getExpireTime()) + .append(" ").append(attributes.getMaxCount()); + if (attributes.getOverflowAction() != null) { + b.append(" ").append(attributes.getOverflowAction()); } - if (attribute.getReadable() != null && !attribute.getReadable()) { + if (!attributes.getReadable()) { b.append(" ").append("unreadable"); } return b.toString(); diff --git a/src/main/java/net/spy/memcached/collection/CollectionInsert.java b/src/main/java/net/spy/memcached/collection/CollectionInsert.java index b193fc03e..e7dad5d35 100644 --- a/src/main/java/net/spy/memcached/collection/CollectionInsert.java +++ b/src/main/java/net/spy/memcached/collection/CollectionInsert.java @@ -23,7 +23,7 @@ public abstract class CollectionInsert { protected int flags = 0; protected T value; protected RequestMode requestMode; - protected CollectionAttributes attribute; + protected CreateAttributes createAttributes; protected byte[] elementFlag; protected String str; @@ -31,9 +31,9 @@ protected CollectionInsert() { } protected CollectionInsert(CollectionType type, T value, byte[] elementFlag, - RequestMode requestMode, CollectionAttributes attr) { - if (attr != null) { /* item creation option */ - CollectionCreate.checkOverflowAction(type, attr.getOverflowAction()); + RequestMode requestMode, CreateAttributes createAttributes) { + if (createAttributes != null) { /* item creation option */ + CollectionCreate.checkOverflowAction(type, createAttributes.getOverflowAction()); } if (elementFlag != null) { if (elementFlag.length < 1 || elementFlag.length > ElementFlagFilter.MAX_EFLAG_LENGTH) { @@ -45,7 +45,7 @@ protected CollectionInsert(CollectionType type, T value, byte[] elementFlag, this.value = value; this.elementFlag = elementFlag; this.requestMode = requestMode; - this.attribute = attr; + this.createAttributes = createAttributes; } public String stringify() { @@ -55,8 +55,8 @@ public String stringify() { StringBuilder b = new StringBuilder(); - if (attribute != null) { - b.append(CollectionCreate.makeCreateClause(attribute, flags)); + if (createAttributes != null) { + b.append(CollectionCreate.makeCreateClause(createAttributes, flags)); } // an optional request mode like noreply, pipe and getrim diff --git a/src/main/java/net/spy/memcached/collection/CollectionPipedInsert.java b/src/main/java/net/spy/memcached/collection/CollectionPipedInsert.java index 7f879644b..72024981e 100644 --- a/src/main/java/net/spy/memcached/collection/CollectionPipedInsert.java +++ b/src/main/java/net/spy/memcached/collection/CollectionPipedInsert.java @@ -31,14 +31,14 @@ public abstract class CollectionPipedInsert extends CollectionPipe { protected final String key; - protected final CollectionAttributes attribute; + protected final CreateAttributes createAttributes; protected final Transcoder tc; - protected CollectionPipedInsert(String key, CollectionAttributes attribute, + protected CollectionPipedInsert(String key, CreateAttributes createAttributes, Transcoder tc, int itemCount) { super(itemCount); this.key = key; - this.attribute = attribute; + this.createAttributes = createAttributes; this.tc = tc; } @@ -52,10 +52,11 @@ public static class ListPipedInsert extends CollectionPipedInsert { private final int index; public ListPipedInsert(String key, int index, Collection list, - CollectionAttributes attr, Transcoder tc) { - super(key, attr, tc, list.size()); - if (attr != null) { /* item creation option */ - CollectionCreate.checkOverflowAction(CollectionType.list, attr.getOverflowAction()); + CreateAttributes createAttributes, Transcoder tc) { + super(key, createAttributes, tc, list.size()); + if (createAttributes != null) { /* item creation option */ + CollectionCreate.checkOverflowAction(CollectionType.list, + createAttributes.getOverflowAction()); } this.index = index; this.list = list; @@ -86,8 +87,8 @@ public ByteBuffer getAsciiCommand() { // create ascii operation string int eSize = encodedList.size(); - String createOption = attribute != null ? - CollectionCreate.makeCreateClause(attribute, cd.getFlags()) : ""; + String createClause = createAttributes != null ? + CollectionCreate.makeCreateClause(createAttributes, cd.getFlags()) : ""; for (i = 0; i < eSize; i++) { byte[] each = encodedList.get(i); int eIndex = index; @@ -95,7 +96,7 @@ public ByteBuffer getAsciiCommand() { eIndex += (i + nextOpIndex); } setArguments(bb, COMMAND, key, eIndex, each.length, - createOption, (i < eSize - 1) ? PIPE : ""); + createClause, (i < eSize - 1) ? PIPE : ""); bb.put(each); bb.put(CRLF); } @@ -116,10 +117,11 @@ public static class SetPipedInsert extends CollectionPipedInsert { private final Collection set; public SetPipedInsert(String key, Collection set, - CollectionAttributes attr, Transcoder tc) { - super(key, attr, tc, set.size()); - if (attr != null) { /* item creation option */ - CollectionCreate.checkOverflowAction(CollectionType.set, attr.getOverflowAction()); + CreateAttributes createAttributes, Transcoder tc) { + super(key, createAttributes, tc, set.size()); + if (createAttributes != null) { /* item creation option */ + CollectionCreate.checkOverflowAction(CollectionType.set, + createAttributes.getOverflowAction()); } this.set = set; } @@ -149,12 +151,12 @@ public ByteBuffer getAsciiCommand() { // create ascii operation string int eSize = encodedList.size(); - String createOption = attribute != null ? - CollectionCreate.makeCreateClause(attribute, cd.getFlags()) : ""; + String createClause = createAttributes != null ? + CollectionCreate.makeCreateClause(createAttributes, cd.getFlags()) : ""; for (i = 0; i < eSize; i++) { byte[] each = encodedList.get(i); setArguments(bb, COMMAND, key, each.length, - createOption, (i < eSize - 1) ? PIPE : ""); + createClause, (i < eSize - 1) ? PIPE : ""); bb.put(each); bb.put(CRLF); } @@ -175,10 +177,11 @@ public static class BTreePipedInsert extends CollectionPipedInsert { private final Map map; public BTreePipedInsert(String key, Map map, - CollectionAttributes attr, Transcoder tc) { - super(key, attr, tc, map.size()); - if (attr != null) { /* item creation option */ - CollectionCreate.checkOverflowAction(CollectionType.btree, attr.getOverflowAction()); + CreateAttributes createAttributes, Transcoder tc) { + super(key, createAttributes, tc, map.size()); + if (createAttributes != null) { /* item creation option */ + CollectionCreate.checkOverflowAction(CollectionType.btree, + createAttributes.getOverflowAction()); } this.map = map; } @@ -211,13 +214,13 @@ public ByteBuffer getAsciiCommand() { ByteBuffer bb = ByteBuffer.allocate(capacity); // create ascii operation string - String createOption = attribute != null ? - CollectionCreate.makeCreateClause(attribute, cd.getFlags()) : ""; + String createClause = createAttributes != null ? + CollectionCreate.makeCreateClause(createAttributes, cd.getFlags()) : ""; for (i = 0; i < eSize; i++) { Long bkey = bkeyList.get(i); byte[] value = encodedList.get(i); setArguments(bb, COMMAND, key, bkey, value.length, - createOption, (i < eSize - 1) ? PIPE : ""); + createClause, (i < eSize - 1) ? PIPE : ""); bb.put(value); bb.put(CRLF); } @@ -238,10 +241,11 @@ public static class ByteArraysBTreePipedInsert extends CollectionPipedInsert< private final List> elements; public ByteArraysBTreePipedInsert(String key, List> elements, - CollectionAttributes attr, Transcoder tc) { - super(key, attr, tc, elements.size()); - if (attr != null) { /* item creation option */ - CollectionCreate.checkOverflowAction(CollectionType.btree, attr.getOverflowAction()); + CreateAttributes createAttributes, Transcoder tc) { + super(key, createAttributes, tc, elements.size()); + if (createAttributes != null) { /* item creation option */ + CollectionCreate.checkOverflowAction(CollectionType.btree, + createAttributes.getOverflowAction()); } this.elements = elements; } @@ -274,14 +278,14 @@ public ByteBuffer getAsciiCommand() { ByteBuffer bb = ByteBuffer.allocate(capacity); // create ascii operation string - String createOption = attribute != null ? - CollectionCreate.makeCreateClause(attribute, cd.getFlags()) : ""; + String createClause = createAttributes != null ? + CollectionCreate.makeCreateClause(createAttributes, cd.getFlags()) : ""; for (i = 0; i < eSize; i++) { Element element = elements.get(i + nextOpIndex); byte[] value = encodedList.get(i); setArguments(bb, COMMAND, key, element.getStringBkey(), element.getStringEFlag(), value.length, - createOption, (i < eSize - 1) ? PIPE : ""); + createClause, (i < eSize - 1) ? PIPE : ""); bb.put(value); bb.put(CRLF); } @@ -302,10 +306,11 @@ public static class MapPipedInsert extends CollectionPipedInsert { private final Map map; public MapPipedInsert(String key, Map map, - CollectionAttributes attr, Transcoder tc) { - super(key, attr, tc, map.size()); - if (attr != null) { /* item creation option */ - CollectionCreate.checkOverflowAction(CollectionType.map, attr.getOverflowAction()); + CreateAttributes createAttributes, Transcoder tc) { + super(key, createAttributes, tc, map.size()); + if (createAttributes != null) { /* item creation option */ + CollectionCreate.checkOverflowAction(CollectionType.map, + createAttributes.getOverflowAction()); } this.map = map; } @@ -338,13 +343,13 @@ public ByteBuffer getAsciiCommand() { ByteBuffer bb = ByteBuffer.allocate(capacity); // create ascii operation string - String createOption = attribute != null ? - CollectionCreate.makeCreateClause(attribute, cd.getFlags()) : ""; + String createClause = createAttributes != null ? + CollectionCreate.makeCreateClause(createAttributes, cd.getFlags()) : ""; for (i = 0; i < eSize; i++) { String mkey = mkeyList.get(i); byte[] value = encodedList.get(i); setArguments(bb, COMMAND, key, mkey, value.length, - createOption, (i < eSize - 1) ? PIPE : ""); + createClause, (i < eSize - 1) ? PIPE : ""); bb.put(value); bb.put(CRLF); } diff --git a/src/main/java/net/spy/memcached/collection/CreateAttributes.java b/src/main/java/net/spy/memcached/collection/CreateAttributes.java new file mode 100644 index 000000000..e8fff6248 --- /dev/null +++ b/src/main/java/net/spy/memcached/collection/CreateAttributes.java @@ -0,0 +1,124 @@ +/* + * arcus-java-client : Arcus Java client + * Copyright 2010-2014 NAVER Corp. + * Copyright 2014-present JaM2in Co., Ltd. + * + * Licensed 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 net.spy.memcached.collection; + +/** + * Attributes used when creating a collection (also carried by insert-with-create). + * + *

Unlike {@link CollectionAttributes}, the expiration time is kept as a + * {@code long} so that Unix timestamp values beyond the {@code int} range + * (e.g. absolute expiration dates after year 2038) can be sent to the server. + */ +public final class CreateAttributes { + + private static final long DEFAULT_EXPIRE_TIME = 0L; + private static final long DEFAULT_MAX_COUNT = 4_000L; + private static final boolean DEFAULT_READABLE = true; + + public static final CreateAttributes DEFAULT = CreateAttributes.builder() + .expireTime(DEFAULT_EXPIRE_TIME) + .maxCount(DEFAULT_MAX_COUNT) + .overflowAction(null) + .readable(DEFAULT_READABLE) + .build(); + + private final long expireTime; + private final long maxCount; + private final CollectionOverflowAction overflowAction; + private final boolean readable; + + private CreateAttributes(Builder builder) { + this.expireTime = builder.expireTime; + this.maxCount = builder.maxCount; + this.overflowAction = builder.overflowAction; + this.readable = builder.readable; + } + + public static Builder builder() { + return new Builder(); + } + + /** + * Converts the existing API's attributes into a CreateAttributes. + * + * @param attr attributes to convert, may be null + * @return converted CreateAttributes, or null if the given attributes is null + */ + public static CreateAttributes of(CollectionAttributes attr) { + if (attr == null) { + return null; + } + + return CreateAttributes.builder() + .expireTime(attr.getExpireTime() != null ? attr.getExpireTime() : DEFAULT_EXPIRE_TIME) + .maxCount(attr.getMaxCount() != null ? attr.getMaxCount() : DEFAULT_MAX_COUNT) + .overflowAction(attr.getOverflowAction()) + .readable(attr.getReadable() == null || attr.getReadable()) + .build(); + } + + public long getExpireTime() { + return this.expireTime; + } + + public long getMaxCount() { + return this.maxCount; + } + + public CollectionOverflowAction getOverflowAction() { + return this.overflowAction; + } + + public boolean getReadable() { + return this.readable; + } + + public static final class Builder { + private long expireTime = DEFAULT_EXPIRE_TIME; + private long maxCount = DEFAULT_MAX_COUNT; + private CollectionOverflowAction overflowAction; + private boolean readable = DEFAULT_READABLE; + + private Builder() { + } + + public Builder expireTime(long expireTime) { + this.expireTime = expireTime; + return this; + } + + public Builder maxCount(long maxCount) { + this.maxCount = maxCount; + return this; + } + + public Builder overflowAction(CollectionOverflowAction overflowAction) { + this.overflowAction = overflowAction; + return this; + } + + public Builder readable(boolean readable) { + this.readable = readable; + return this; + } + + public CreateAttributes build() { + return new CreateAttributes(this); + } + } +} diff --git a/src/main/java/net/spy/memcached/collection/ListCreate.java b/src/main/java/net/spy/memcached/collection/ListCreate.java index 8451d635e..3876802f4 100644 --- a/src/main/java/net/spy/memcached/collection/ListCreate.java +++ b/src/main/java/net/spy/memcached/collection/ListCreate.java @@ -20,9 +20,8 @@ public class ListCreate extends CollectionCreate { private static final String COMMAND = "lop create"; - public ListCreate(int flags, Integer expTime, Long maxCount, - CollectionOverflowAction overflowAction, Boolean readable, boolean noreply) { - super(CollectionType.list, flags, expTime, maxCount, overflowAction, readable, noreply); + public ListCreate(int flags, CreateAttributes option, boolean noreply) { + super(CollectionType.list, flags, option, noreply); } public String getCommand() { diff --git a/src/main/java/net/spy/memcached/collection/ListInsert.java b/src/main/java/net/spy/memcached/collection/ListInsert.java index 5f69a3caa..4fbef41ea 100644 --- a/src/main/java/net/spy/memcached/collection/ListInsert.java +++ b/src/main/java/net/spy/memcached/collection/ListInsert.java @@ -20,8 +20,8 @@ public class ListInsert extends CollectionInsert { private static final String COMMAND = "lop insert"; - public ListInsert(T value, RequestMode requestMode, CollectionAttributes attr) { - super(CollectionType.list, value, null, requestMode, attr); + public ListInsert(T value, RequestMode requestMode, CreateAttributes createAttributes) { + super(CollectionType.list, value, null, requestMode, createAttributes); } public String getCommand() { diff --git a/src/main/java/net/spy/memcached/collection/MapCreate.java b/src/main/java/net/spy/memcached/collection/MapCreate.java index 74ca6992a..3b2913589 100644 --- a/src/main/java/net/spy/memcached/collection/MapCreate.java +++ b/src/main/java/net/spy/memcached/collection/MapCreate.java @@ -20,8 +20,8 @@ public class MapCreate extends CollectionCreate { private static final String COMMAND = "mop create"; - public MapCreate(int flags, Integer expTime, Long maxCount, Boolean readable, boolean noreply) { - super(CollectionType.map, flags, expTime, maxCount, null, readable, noreply); + public MapCreate(int flags, CreateAttributes option, boolean noreply) { + super(CollectionType.map, flags, option, noreply); } public String getCommand() { diff --git a/src/main/java/net/spy/memcached/collection/MapInsert.java b/src/main/java/net/spy/memcached/collection/MapInsert.java index 7abf77a80..d2c594bb8 100644 --- a/src/main/java/net/spy/memcached/collection/MapInsert.java +++ b/src/main/java/net/spy/memcached/collection/MapInsert.java @@ -20,8 +20,8 @@ public class MapInsert extends CollectionInsert { private static final String COMMAND = "mop insert"; - public MapInsert(T value, RequestMode requestMode, CollectionAttributes attr) { - super(CollectionType.map, value, null, requestMode, attr); + public MapInsert(T value, RequestMode requestMode, CreateAttributes createAttributes) { + super(CollectionType.map, value, null, requestMode, createAttributes); } public String getCommand() { diff --git a/src/main/java/net/spy/memcached/collection/MapUpsert.java b/src/main/java/net/spy/memcached/collection/MapUpsert.java index cb39f63f9..f250e1f4f 100644 --- a/src/main/java/net/spy/memcached/collection/MapUpsert.java +++ b/src/main/java/net/spy/memcached/collection/MapUpsert.java @@ -4,8 +4,8 @@ public class MapUpsert extends CollectionInsert { private static final String COMMAND = "mop upsert"; - public MapUpsert(T value, CollectionAttributes attr) { - super(CollectionType.map, value, null, null, attr); + public MapUpsert(T value, CreateAttributes createAttributes) { + super(CollectionType.map, value, null, null, createAttributes); } @Override diff --git a/src/main/java/net/spy/memcached/collection/SetAttributes.java b/src/main/java/net/spy/memcached/collection/SetAttributes.java new file mode 100644 index 000000000..fad2eb5a0 --- /dev/null +++ b/src/main/java/net/spy/memcached/collection/SetAttributes.java @@ -0,0 +1,44 @@ +/* + * arcus-java-client : Arcus Java client + * Copyright 2010-2014 NAVER Corp. + * Copyright 2014-present JaM2in Co., Ltd. + * + * Licensed 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 net.spy.memcached.collection; + +/** + * Contract for producing the {@code setattr} attribute clause. + * Implemented by the v1 {@link Attributes} and + * the v2 {@link net.spy.memcached.v2.attribute.UpdateAttributes} + * so a single setattr operation can serialize either. + * + *

The clause text is produced by {@link #stringify()}. + * {@link #getLength()} returns its length for buffer sizing. + */ +public interface SetAttributes { + + /** + * Serializes the attributes into the {@code setattr} command's attribute clause – + * space-separated {@code name=value} tokens + * (e.g. {@code "expiretime=100 maxcount=1000"}). + * + * @return the attribute clause text + */ + String stringify(); + + /** + * @return the length of {@link #stringify()}, used to size the request buffer + */ + int getLength(); +} diff --git a/src/main/java/net/spy/memcached/collection/SetCreate.java b/src/main/java/net/spy/memcached/collection/SetCreate.java index 2e2314118..6d80b1d4d 100644 --- a/src/main/java/net/spy/memcached/collection/SetCreate.java +++ b/src/main/java/net/spy/memcached/collection/SetCreate.java @@ -20,8 +20,8 @@ public class SetCreate extends CollectionCreate { private static final String COMMAND = "sop create"; - public SetCreate(int flags, Integer expTime, Long maxCount, Boolean readable, boolean noreply) { - super(CollectionType.set, flags, expTime, maxCount, null, readable, noreply); + public SetCreate(int flags, CreateAttributes option, boolean noreply) { + super(CollectionType.set, flags, option, noreply); } public String getCommand() { diff --git a/src/main/java/net/spy/memcached/collection/SetInsert.java b/src/main/java/net/spy/memcached/collection/SetInsert.java index 66097818e..247c82712 100644 --- a/src/main/java/net/spy/memcached/collection/SetInsert.java +++ b/src/main/java/net/spy/memcached/collection/SetInsert.java @@ -20,8 +20,8 @@ public class SetInsert extends CollectionInsert { private static final String COMMAND = "sop insert"; - public SetInsert(T value, RequestMode requestMode, CollectionAttributes attr) { - super(CollectionType.set, value, null, requestMode, attr); + public SetInsert(T value, RequestMode requestMode, CreateAttributes createAttributes) { + super(CollectionType.set, value, null, requestMode, createAttributes); } public String getCommand() { diff --git a/src/main/java/net/spy/memcached/ops/CASOperation.java b/src/main/java/net/spy/memcached/ops/CASOperation.java index eb0ab49f7..988d5e85b 100644 --- a/src/main/java/net/spy/memcached/ops/CASOperation.java +++ b/src/main/java/net/spy/memcached/ops/CASOperation.java @@ -23,7 +23,7 @@ public interface CASOperation extends KeyedOperation { /** * Get the expiration to be set for this operation. */ - int getExpiration(); + long getExpiration(); /** * Get the bytes to be set during this operation. diff --git a/src/main/java/net/spy/memcached/ops/SetAttrOperation.java b/src/main/java/net/spy/memcached/ops/SetAttrOperation.java index ee53352ef..4591e6e89 100644 --- a/src/main/java/net/spy/memcached/ops/SetAttrOperation.java +++ b/src/main/java/net/spy/memcached/ops/SetAttrOperation.java @@ -16,13 +16,13 @@ */ package net.spy.memcached.ops; -import net.spy.memcached.collection.Attributes; +import net.spy.memcached.collection.SetAttributes; /** * SetAttr operation. */ public interface SetAttrOperation extends KeyedOperation { - Attributes getAttributes(); + SetAttributes getAttributes(); } diff --git a/src/main/java/net/spy/memcached/ops/StoreOperation.java b/src/main/java/net/spy/memcached/ops/StoreOperation.java index 548d5a0f8..f2267abae 100644 --- a/src/main/java/net/spy/memcached/ops/StoreOperation.java +++ b/src/main/java/net/spy/memcached/ops/StoreOperation.java @@ -18,7 +18,7 @@ public interface StoreOperation extends KeyedOperation { /** * Get the expiration value to be set. */ - int getExpiration(); + long getExpiration(); /** * Get the bytes to be set during this operation. diff --git a/src/main/java/net/spy/memcached/ops/TouchOperation.java b/src/main/java/net/spy/memcached/ops/TouchOperation.java index c0b866ec7..775a88408 100644 --- a/src/main/java/net/spy/memcached/ops/TouchOperation.java +++ b/src/main/java/net/spy/memcached/ops/TouchOperation.java @@ -26,5 +26,5 @@ public interface TouchOperation extends KeyedOperation { /** * Get the expiration to set in case of a new entry. */ - int getExpiration(); + long getExpiration(); } diff --git a/src/main/java/net/spy/memcached/protocol/ascii/AsciiOperationFactory.java b/src/main/java/net/spy/memcached/protocol/ascii/AsciiOperationFactory.java index 1f4da20ae..5ea9e226b 100644 --- a/src/main/java/net/spy/memcached/protocol/ascii/AsciiOperationFactory.java +++ b/src/main/java/net/spy/memcached/protocol/ascii/AsciiOperationFactory.java @@ -20,7 +20,6 @@ import javax.security.sasl.SaslClient; -import net.spy.memcached.collection.Attributes; import net.spy.memcached.collection.BTreeFindPosition; import net.spy.memcached.collection.BTreeFindPositionWithGet; import net.spy.memcached.collection.BTreeGetBulk; @@ -38,6 +37,7 @@ import net.spy.memcached.collection.CollectionPipedInsert; import net.spy.memcached.collection.CollectionPipedUpdate; import net.spy.memcached.collection.CollectionUpdate; +import net.spy.memcached.collection.SetAttributes; import net.spy.memcached.collection.SetPipedExist; import net.spy.memcached.ops.BTreeFindPositionOperation; import net.spy.memcached.ops.BTreeFindPositionWithGetOperation; @@ -85,143 +85,172 @@ */ public class AsciiOperationFactory extends BaseOperationFactory { + @Override public DeleteOperation delete(String key, OperationCallback cb) { return new DeleteOperationImpl(key, cb); } + @Override public FlushOperation flush(int delay, OperationCallback cb) { return new FlushOperationImpl(delay, cb); } + @Override public GetOperation get(String key, GetOperation.Callback cb) { return new GetOperationImpl(key, cb); } + @Override public GetOperation get(Collection keys, GetOperation.Callback cb, boolean isMGet) { return new GetOperationImpl(keys, cb, isMGet); } + @Override public GetsOperation gets(String key, GetsOperation.Callback cb) { return new GetsOperationImpl(key, cb); } + @Override public GetsOperation gets(Collection keys, GetsOperation.Callback cb, boolean isMGet) { return new GetsOperationImpl(keys, cb, isMGet); } - public GetOperation getAndTouch(String key, int expiration, GetOperation.Callback cb) { - return new GetAndTouchOperationImpl(key, expiration, cb); + @Override + public GetOperation getAndTouch(String key, long exp, GetOperation.Callback cb) { + return new GetAndTouchOperationImpl(key, exp, cb); } - public GetsOperation getsAndTouch(String key, int expiration, GetsOperation.Callback cb) { - return new GetsAndTouchOperationImpl(key, expiration, cb); + @Override + public GetsOperation getsAndTouch(String key, long exp, GetsOperation.Callback cb) { + return new GetsAndTouchOperationImpl(key, exp, cb); } + @Override public MutatorOperation mutate(Mutator m, String key, int by, - long def, int exp, OperationCallback cb) { + long def, long exp, OperationCallback cb) { return new MutatorOperationImpl(m, key, by, def, exp, cb); } + @Override public StatsOperation stats(String arg, StatsOperation.Callback cb) { return new StatsOperationImpl(arg, cb); } + @Override public StoreOperation store(StoreType storeType, String key, int flags, - int exp, byte[] data, OperationCallback cb) { + long exp, byte[] data, OperationCallback cb) { return new StoreOperationImpl(storeType, key, flags, exp, data, cb); } - public TouchOperation touch(String key, int expiration, OperationCallback cb) { - return new TouchOperationImpl(key, expiration, cb); + @Override + public TouchOperation touch(String key, long exp, OperationCallback cb) { + return new TouchOperationImpl(key, exp, cb); } + @Override public VersionOperation version(OperationCallback cb) { return new VersionOperationImpl(cb); } + @Override public NoopOperation noop(OperationCallback cb) { return new VersionOperationImpl(cb); } + @Override public CASOperation cas(StoreType type, String key, long casId, int flags, - int exp, byte[] data, OperationCallback cb) { + long exp, byte[] data, OperationCallback cb) { return new CASOperationImpl(key, casId, flags, exp, data, cb); } + @Override public ConcatenationOperation cat(ConcatenationType catType, long casId, String key, byte[] data, OperationCallback cb) { return new ConcatenationOperationImpl(catType, key, data, cb); } + @Override public SASLMechsOperation saslMechs(boolean isInternal, OperationCallback cb) { return new SASLMechsOperationImpl(isInternal, cb); } + @Override public SASLStepOperation saslStep(SaslClient sc, byte[] challenge, OperationCallback cb) { return new SASLStepOperationImpl(sc, challenge, cb); } + @Override public SASLAuthOperation saslAuth(SaslClient sc, OperationCallback cb) { return new SASLAuthOperationImpl(sc, cb); } - public SetAttrOperation setAttr(String key, Attributes attrs, - OperationCallback cb) { + @Override + public SetAttrOperation setAttr(String key, SetAttributes attrs, OperationCallback cb) { return new SetAttrOperationImpl(key, attrs, cb); } + @Override public GetAttrOperation getAttr(String key, GetAttrOperation.Callback cb) { return new GetAttrOperationImpl(key, cb); } + @Override public CollectionInsertOperation collectionInsert(String key, String subkey, CollectionInsert collectionInsert, byte[] data, OperationCallback cb) { return new CollectionInsertOperationImpl(key, subkey, - collectionInsert, data, cb); + collectionInsert, data, cb); } + @Override public CollectionPipedInsertOperation collectionPipedInsert(String key, CollectionPipedInsert insert, OperationCallback cb) { return new CollectionPipedInsertOperationImpl(key, insert, cb); } + @Override public CollectionGetOperation collectionGet(String key, CollectionGet collectionGet, CollectionGetOperation.Callback cb) { return new CollectionGetOperationImpl(key, collectionGet, cb); } + @Override public CollectionDeleteOperation collectionDelete(String key, CollectionDelete collectionDelete, OperationCallback cb) { return new CollectionDeleteOperationImpl(key, collectionDelete, cb); } + @Override public CollectionExistOperation collectionExist(String key, String subkey, CollectionExist collectionExist, OperationCallback cb) { return new CollectionExistOperationImpl(key, subkey, collectionExist, cb); } + @Override public CollectionCreateOperation collectionCreate(String key, CollectionCreate collectionCreate, OperationCallback cb) { return new CollectionCreateOperationImpl(key, collectionCreate, cb); } + @Override public CollectionCountOperation collectionCount(String key, CollectionCount collectionCount, OperationCallback cb) { return new CollectionCountOperationImpl(key, collectionCount, cb); } + @Override public FlushOperation flush(String prefix, int delay, boolean noreply, OperationCallback cb) { return new FlushByPrefixOperationImpl(prefix, delay, noreply, cb); } + @Override public BTreeSortMergeGetOperation bopsmget(BTreeSMGet smGet, BTreeSortMergeGetOperation.Callback cb) { return new BTreeSortMergeGetOperationImpl(smGet, cb); @@ -234,7 +263,7 @@ public CollectionUpdateOperation collectionUpdate(String key, byte[] data, OperationCallback cb) { return new CollectionUpdateOperationImpl(key, subkey, collectionUpdate, - data, cb); + data, cb); } @Override diff --git a/src/main/java/net/spy/memcached/protocol/ascii/BaseGetOpImpl.java b/src/main/java/net/spy/memcached/protocol/ascii/BaseGetOpImpl.java index 3ddd7fa1e..6f7171932 100644 --- a/src/main/java/net/spy/memcached/protocol/ascii/BaseGetOpImpl.java +++ b/src/main/java/net/spy/memcached/protocol/ascii/BaseGetOpImpl.java @@ -40,7 +40,7 @@ abstract class BaseGetOpImpl extends OperationImpl { private final String cmd; private final Collection keys; private String currentKey = null; - private final int exp; + private final long exp; // using only gat, gats private long casValue = 0; private int currentFlags = 0; private byte[] data = null; @@ -62,7 +62,7 @@ public BaseGetOpImpl(String c, /** * For GetAndTouchOperationImpl, GetsAndTouchOperationImpl Only */ - public BaseGetOpImpl(String c, int e, + public BaseGetOpImpl(String c, long e, OperationCallback cb, Collection k) { super(cb); cmd = c; @@ -240,7 +240,4 @@ public boolean isBulkOperation() { return keys.size() > 1; } - public int getExpiration() { - return exp; - } } diff --git a/src/main/java/net/spy/memcached/protocol/ascii/BaseStoreOperationImpl.java b/src/main/java/net/spy/memcached/protocol/ascii/BaseStoreOperationImpl.java index 031076086..640b17cf1 100644 --- a/src/main/java/net/spy/memcached/protocol/ascii/BaseStoreOperationImpl.java +++ b/src/main/java/net/spy/memcached/protocol/ascii/BaseStoreOperationImpl.java @@ -50,10 +50,10 @@ abstract class BaseStoreOperationImpl extends OperationImpl { protected final String type; protected final String key; protected final int flags; - protected final int exp; + protected final long exp; protected final byte[] data; - public BaseStoreOperationImpl(String t, String k, int f, int e, + public BaseStoreOperationImpl(String t, String k, int f, long e, byte[] d, OperationCallback cb) { super(cb); type = t; @@ -111,7 +111,7 @@ public int getFlags() { return flags; } - public int getExpiration() { + public long getExpiration() { return exp; } diff --git a/src/main/java/net/spy/memcached/protocol/ascii/CASOperationImpl.java b/src/main/java/net/spy/memcached/protocol/ascii/CASOperationImpl.java index 16718c043..81377fdda 100644 --- a/src/main/java/net/spy/memcached/protocol/ascii/CASOperationImpl.java +++ b/src/main/java/net/spy/memcached/protocol/ascii/CASOperationImpl.java @@ -57,10 +57,10 @@ class CASOperationImpl extends OperationImpl implements CASOperation { private final String key; private final long casValue; private final int flags; - private final int exp; + private final long exp; private final byte[] data; - public CASOperationImpl(String k, long c, int f, int e, + public CASOperationImpl(String k, long c, int f, long e, byte[] d, OperationCallback cb) { super(cb); key = k; @@ -118,7 +118,7 @@ public long getCasValue() { return casValue; } - public int getExpiration() { + public long getExpiration() { return exp; } diff --git a/src/main/java/net/spy/memcached/protocol/ascii/GetAndTouchOperationImpl.java b/src/main/java/net/spy/memcached/protocol/ascii/GetAndTouchOperationImpl.java index 85952777a..f0427ad81 100644 --- a/src/main/java/net/spy/memcached/protocol/ascii/GetAndTouchOperationImpl.java +++ b/src/main/java/net/spy/memcached/protocol/ascii/GetAndTouchOperationImpl.java @@ -29,7 +29,7 @@ class GetAndTouchOperationImpl extends BaseGetOpImpl implements GetOperation { private static final String CMD = "gat"; - public GetAndTouchOperationImpl(String k, int e, GetOperation.Callback cb) { + public GetAndTouchOperationImpl(String k, long e, GetOperation.Callback cb) { super(CMD, e, cb, Collections.singleton(k)); setAPIType(APIType.GAT); } diff --git a/src/main/java/net/spy/memcached/protocol/ascii/GetsAndTouchOperationImpl.java b/src/main/java/net/spy/memcached/protocol/ascii/GetsAndTouchOperationImpl.java index 0945c6242..5a4da2180 100644 --- a/src/main/java/net/spy/memcached/protocol/ascii/GetsAndTouchOperationImpl.java +++ b/src/main/java/net/spy/memcached/protocol/ascii/GetsAndTouchOperationImpl.java @@ -29,7 +29,7 @@ class GetsAndTouchOperationImpl extends BaseGetOpImpl implements GetsOperation { private static final String CMD = "gats"; - public GetsAndTouchOperationImpl(String k, int e, GetsOperation.Callback cb) { + public GetsAndTouchOperationImpl(String k, long e, GetsOperation.Callback cb) { super(CMD, e, cb, Collections.singleton(k)); setAPIType(APIType.GATS); } diff --git a/src/main/java/net/spy/memcached/protocol/ascii/MutatorOperationImpl.java b/src/main/java/net/spy/memcached/protocol/ascii/MutatorOperationImpl.java index eb5b482bf..1df240ae9 100644 --- a/src/main/java/net/spy/memcached/protocol/ascii/MutatorOperationImpl.java +++ b/src/main/java/net/spy/memcached/protocol/ascii/MutatorOperationImpl.java @@ -51,9 +51,9 @@ final class MutatorOperationImpl extends OperationImpl private final String key; private final int amount; private final long def; - private final int exp; + private final long exp; - public MutatorOperationImpl(Mutator m, String k, int amt, long d, int e, + public MutatorOperationImpl(Mutator m, String k, int amt, long d, long e, OperationCallback c) { super(c); mutator = m; diff --git a/src/main/java/net/spy/memcached/protocol/ascii/SetAttrOperationImpl.java b/src/main/java/net/spy/memcached/protocol/ascii/SetAttrOperationImpl.java index 928ef3b11..1a5a06ae0 100644 --- a/src/main/java/net/spy/memcached/protocol/ascii/SetAttrOperationImpl.java +++ b/src/main/java/net/spy/memcached/protocol/ascii/SetAttrOperationImpl.java @@ -23,9 +23,9 @@ import java.util.Collections; import net.spy.memcached.KeyUtil; -import net.spy.memcached.collection.Attributes; import net.spy.memcached.collection.CollectionAttributes; import net.spy.memcached.collection.CollectionResponse; +import net.spy.memcached.collection.SetAttributes; import net.spy.memcached.ops.APIType; import net.spy.memcached.ops.CollectionOperationStatus; import net.spy.memcached.ops.OperationCallback; @@ -52,9 +52,9 @@ class SetAttrOperationImpl extends OperationImpl false, "ATTR_ERROR bad value", CollectionResponse.ATTR_ERROR_BAD_VALUE); protected final String key; - protected final Attributes attrs; + protected final SetAttributes attrs; - public SetAttrOperationImpl(String key, Attributes attrs, + public SetAttrOperationImpl(String key, SetAttributes attrs, OperationCallback cb) { super(cb); this.key = key; @@ -106,7 +106,8 @@ public Collection getKeys() { return Collections.singleton(key); } - public Attributes getAttributes() { + @Override + public SetAttributes getAttributes() { return attrs; } diff --git a/src/main/java/net/spy/memcached/protocol/ascii/StoreOperationImpl.java b/src/main/java/net/spy/memcached/protocol/ascii/StoreOperationImpl.java index 95158bd4c..c0fe81aca 100644 --- a/src/main/java/net/spy/memcached/protocol/ascii/StoreOperationImpl.java +++ b/src/main/java/net/spy/memcached/protocol/ascii/StoreOperationImpl.java @@ -32,7 +32,7 @@ final class StoreOperationImpl extends BaseStoreOperationImpl private final StoreType storeType; - public StoreOperationImpl(StoreType t, String k, int f, int e, + public StoreOperationImpl(StoreType t, String k, int f, long e, byte[] d, OperationCallback cb) { super(t.name(), k, f, e, d, cb); storeType = t; diff --git a/src/main/java/net/spy/memcached/protocol/ascii/TouchOperationImpl.java b/src/main/java/net/spy/memcached/protocol/ascii/TouchOperationImpl.java index aa2a2957a..29ce9b578 100644 --- a/src/main/java/net/spy/memcached/protocol/ascii/TouchOperationImpl.java +++ b/src/main/java/net/spy/memcached/protocol/ascii/TouchOperationImpl.java @@ -42,12 +42,12 @@ final class TouchOperationImpl extends OperationImpl implements TouchOperation { StatusCode.ERR_NOT_FOUND); private final String key; - private final int exp; + private final long exp; - public TouchOperationImpl(String k, int t, OperationCallback cb) { + public TouchOperationImpl(String k, long e, OperationCallback cb) { super(cb); key = k; - exp = t; + exp = e; } public Collection getKeys() { @@ -83,7 +83,7 @@ public void initialize() { } @Override - public int getExpiration() { + public long getExpiration() { return exp; } diff --git a/src/main/java/net/spy/memcached/protocol/binary/BinaryOperationFactory.java b/src/main/java/net/spy/memcached/protocol/binary/BinaryOperationFactory.java index 6e8f159f7..361442cb8 100644 --- a/src/main/java/net/spy/memcached/protocol/binary/BinaryOperationFactory.java +++ b/src/main/java/net/spy/memcached/protocol/binary/BinaryOperationFactory.java @@ -20,7 +20,6 @@ import javax.security.sasl.SaslClient; -import net.spy.memcached.collection.Attributes; import net.spy.memcached.collection.BTreeFindPosition; import net.spy.memcached.collection.BTreeFindPositionWithGet; import net.spy.memcached.collection.BTreeGetBulk; @@ -38,6 +37,7 @@ import net.spy.memcached.collection.CollectionPipedInsert; import net.spy.memcached.collection.CollectionPipedUpdate; import net.spy.memcached.collection.CollectionUpdate; +import net.spy.memcached.collection.SetAttributes; import net.spy.memcached.collection.SetPipedExist; import net.spy.memcached.ops.BTreeFindPositionOperation; import net.spy.memcached.ops.BTreeFindPositionWithGetOperation; @@ -86,107 +86,139 @@ */ public class BinaryOperationFactory extends BaseOperationFactory { + @Override public DeleteOperation delete(String key, OperationCallback operationCallback) { return new DeleteOperationImpl(key, operationCallback); } + @Override public FlushOperation flush(int delay, OperationCallback cb) { return new FlushOperationImpl(cb); } + @Override public GetOperation get(String key, Callback callback) { return new GetOperationImpl(key, callback); } + @Override public GetOperation get(Collection keys, Callback cb, boolean isMGet) { return new MultiGetOperationImpl(keys, cb); } + @Override public GetsOperation gets(String key, GetsOperation.Callback cb) { return new GetOperationImpl(key, cb); } + @Override public GetsOperation gets(Collection keys, GetsOperation.Callback cb, boolean isMGet) { throw new RuntimeException( "multiple key gets is not supported in binary protocol yet."); } - public GetOperation getAndTouch(String key, int expiration, GetOperation.Callback cb) { + @Override + public GetOperation getAndTouch(String key, long exp, GetOperation.Callback cb) { throw new RuntimeException( "GetAndTouchOperation is not supported in binary protocol yet."); } - public GetsOperation getsAndTouch(String key, int expiration, GetsOperation.Callback cb) { + @Override + public GetsOperation getsAndTouch(String key, long exp, GetsOperation.Callback cb) { throw new RuntimeException( "GetsAndTouchOperation is not supported in binary protocol yet."); } + @Override public MutatorOperation mutate(Mutator m, String key, int by, - long def, int exp, OperationCallback cb) { - return new MutatorOperationImpl(m, key, by, def, exp, cb); + long def, long exp, OperationCallback cb) { + if (exp > Integer.MAX_VALUE) { + throw new IllegalArgumentException( + "Binary protocol does not support expiration time beyond int range."); + } + return new MutatorOperationImpl(m, key, by, def, (int) exp, cb); } + @Override public StatsOperation stats(String arg, net.spy.memcached.ops.StatsOperation.Callback cb) { return new StatsOperationImpl(arg, cb); } + @Override public StoreOperation store(StoreType storeType, String key, int flags, - int exp, byte[] data, OperationCallback cb) { - return new StoreOperationImpl(storeType, key, flags, exp, data, 0, cb); + long exp, byte[] data, OperationCallback cb) { + if (exp > Integer.MAX_VALUE) { + throw new IllegalArgumentException( + "Binary protocol does not support expiration time beyond int range."); + } + return new StoreOperationImpl(storeType, key, flags, (int) exp, data, 0, cb); } - public TouchOperation touch(String key, int expiration, OperationCallback cb) { + @Override + public TouchOperation touch(String key, long exp, OperationCallback cb) { throw new RuntimeException( "TouchOperation is not supported in binary protocol yet."); } + @Override public VersionOperation version(OperationCallback cb) { return new VersionOperationImpl(cb); } + @Override public NoopOperation noop(OperationCallback cb) { return new NoopOperationImpl(cb); } + @Override public CASOperation cas(StoreType type, String key, long casId, int flags, - int exp, byte[] data, OperationCallback cb) { - return new StoreOperationImpl(type, key, flags, exp, data, - casId, cb); + long exp, byte[] data, OperationCallback cb) { + if (exp > Integer.MAX_VALUE) { + throw new IllegalArgumentException( + "Binary protocol does not support expiration time beyond int range."); + } + return new StoreOperationImpl(type, key, flags, (int) exp, data, casId, cb); } + @Override public ConcatenationOperation cat(ConcatenationType catType, long casId, String key, byte[] data, OperationCallback cb) { return new ConcatenationOperationImpl(catType, key, data, casId, cb); } + @Override public SASLAuthOperation saslAuth(SaslClient sc, OperationCallback cb) { return new SASLAuthOperationImpl(sc, cb); } + @Override public SASLMechsOperation saslMechs(boolean isInternal, OperationCallback cb) { return new SASLMechsOperationImpl(isInternal, cb); } + @Override public SASLStepOperation saslStep(SaslClient sc, byte[] challenge, OperationCallback cb) { return new SASLStepOperationImpl(sc, challenge, cb); } //// UNSUPPORTED //// - - public SetAttrOperation setAttr(String key, Attributes attrs, + @Override + public SetAttrOperation setAttr(String key, SetAttributes attrs, OperationCallback cb) { throw new RuntimeException( "SetAttrOperation is not supported in binary protocol yet."); } + @Override public GetAttrOperation getAttr(String key, net.spy.memcached.ops.GetAttrOperation.Callback cb) { throw new RuntimeException( "GetAttrOperation is not supported in binary protocol yet."); } + @Override public CollectionInsertOperation collectionInsert(String key, String subkey, CollectionInsert collectionInsert, byte[] data, @@ -195,6 +227,7 @@ public CollectionInsertOperation collectionInsert(String key, String subkey, "CollectionInsertOperation is not supported in binary protocol yet."); } + @Override public CollectionPipedInsertOperation collectionPipedInsert(String key, CollectionPipedInsert insert, OperationCallback cb) { @@ -202,6 +235,7 @@ public CollectionPipedInsertOperation collectionPipedInsert(String key, "CollectionPipedInsertOperation is not supported in binary protocol yet."); } + @Override public CollectionGetOperation collectionGet(String key, CollectionGet collectionGet, CollectionGetOperation.Callback cb) { @@ -209,6 +243,7 @@ public CollectionGetOperation collectionGet(String key, "CollectionGetOperation is not supported in binary protocol yet."); } + @Override public CollectionDeleteOperation collectionDelete(String key, CollectionDelete collectionDelete, OperationCallback cb) { @@ -216,6 +251,7 @@ public CollectionDeleteOperation collectionDelete(String key, "CollectionDeleteOperation is not supported in binary protocol yet."); } + @Override public CollectionExistOperation collectionExist(String key, String subkey, CollectionExist collectionExist, OperationCallback cb) { @@ -223,6 +259,7 @@ public CollectionExistOperation collectionExist(String key, String subkey, "CollectionExistOperation is not supported in binary protocol yet."); } + @Override public CollectionCreateOperation collectionCreate(String key, CollectionCreate collectionCreate, OperationCallback cb) { @@ -230,6 +267,7 @@ public CollectionCreateOperation collectionCreate(String key, "CollectionCreateOperation is not supported in binary protocol yet."); } + @Override public CollectionCountOperation collectionCount(String key, CollectionCount collectionCount, OperationCallback cb) { @@ -237,6 +275,7 @@ public CollectionCountOperation collectionCount(String key, "CollectionCountOperation is not supported in binary protocol yet."); } + @Override public FlushOperation flush(String prefix, int delay, boolean noreply, OperationCallback cb) { throw new RuntimeException( "Flush by prefix operation is not supported in binary protocol yet."); diff --git a/src/main/java/net/spy/memcached/protocol/binary/OptimizedSetImpl.java b/src/main/java/net/spy/memcached/protocol/binary/OptimizedSetImpl.java index 743bac78d..380b86c29 100644 --- a/src/main/java/net/spy/memcached/protocol/binary/OptimizedSetImpl.java +++ b/src/main/java/net/spy/memcached/protocol/binary/OptimizedSetImpl.java @@ -99,7 +99,7 @@ public void initialize() { bb.putLong(so.getCasValue()); // cas // Extras bb.putInt(so.getFlags()); - bb.putInt(so.getExpiration()); + bb.putInt((int) so.getExpiration()); // the actual key bb.put(keyBytes); // And the value diff --git a/src/main/java/net/spy/memcached/protocol/binary/StoreOperationImpl.java b/src/main/java/net/spy/memcached/protocol/binary/StoreOperationImpl.java index 916133e1d..1a2711acf 100644 --- a/src/main/java/net/spy/memcached/protocol/binary/StoreOperationImpl.java +++ b/src/main/java/net/spy/memcached/protocol/binary/StoreOperationImpl.java @@ -107,7 +107,7 @@ public long getCasValue() { return cas; } - public int getExpiration() { + public long getExpiration() { return exp; } diff --git a/src/main/java/net/spy/memcached/v2/AsyncArcusCommands.java b/src/main/java/net/spy/memcached/v2/AsyncArcusCommands.java index d4ed53b69..ce74b050e 100644 --- a/src/main/java/net/spy/memcached/v2/AsyncArcusCommands.java +++ b/src/main/java/net/spy/memcached/v2/AsyncArcusCommands.java @@ -57,13 +57,13 @@ import net.spy.memcached.collection.BTreeSMGetWithLongTypeBkey; import net.spy.memcached.collection.BTreeUpdate; import net.spy.memcached.collection.BTreeUpsert; -import net.spy.memcached.collection.CollectionAttributes; import net.spy.memcached.collection.CollectionCount; import net.spy.memcached.collection.CollectionCreate; import net.spy.memcached.collection.CollectionDelete; import net.spy.memcached.collection.CollectionInsert; import net.spy.memcached.collection.CollectionMutate; import net.spy.memcached.collection.CollectionUpdate; +import net.spy.memcached.collection.CreateAttributes; import net.spy.memcached.collection.ElementFlagFilter; import net.spy.memcached.collection.ElementValueType; import net.spy.memcached.collection.ListCreate; @@ -132,21 +132,21 @@ public AsyncArcusCommands(Supplier arcusClientSupplier) { } @Override - public ArcusFuture set(String key, int exp, T value) { + public ArcusFuture set(String key, long exp, T value) { return store(StoreType.set, key, exp, value); } @Override - public ArcusFuture add(String key, int exp, T value) { + public ArcusFuture add(String key, long exp, T value) { return store(StoreType.add, key, exp, value); } @Override - public ArcusFuture replace(String key, int exp, T value) { + public ArcusFuture replace(String key, long exp, T value) { return store(StoreType.replace, key, exp, value); } - private ArcusFuture store(StoreType type, String key, int exp, T value) { + private ArcusFuture store(StoreType type, String key, long exp, T value) { AbstractArcusResult result = new AbstractArcusResult<>(new AtomicReference<>()); ArcusFutureImpl future = new ArcusFutureImpl<>(result); CachedData co = tc.encode(value); @@ -187,23 +187,23 @@ public void complete() { } @Override - public ArcusFuture> multiSet(Map items, int exp) { + public ArcusFuture> multiSet(Map items, long exp) { return multiStore(StoreType.set, items, exp); } @Override - public ArcusFuture> multiAdd(Map items, int exp) { + public ArcusFuture> multiAdd(Map items, long exp) { return multiStore(StoreType.add, items, exp); } @Override - public ArcusFuture> multiReplace(Map items, int exp) { + public ArcusFuture> multiReplace(Map items, long exp) { return multiStore(StoreType.replace, items, exp); } private ArcusFuture> multiStore(StoreType type, Map items, - int exp) { + long exp) { Map> keyToFuture = new HashMap<>(items.size()); items.forEach((key, value) -> { @@ -274,7 +274,7 @@ public void complete() { } @Override - public ArcusFuture cas(String key, int exp, T value, long casId) { + public ArcusFuture cas(String key, long exp, T value, long casId) { AbstractArcusResult result = new AbstractArcusResult<>(new AtomicReference<>()); ArcusFutureImpl future = new ArcusFutureImpl<>(result); CachedData co = tc.encode(value); @@ -321,7 +321,7 @@ public ArcusFuture incr(String key, int delta) { } @Override - public ArcusFuture incr(String key, int delta, long initial, int exp) { + public ArcusFuture incr(String key, int delta, long initial, long exp) { if (initial < 0) { throw new IllegalArgumentException("Initial value must be 0 or greater."); } @@ -334,14 +334,14 @@ public ArcusFuture decr(String key, int delta) { } @Override - public ArcusFuture decr(String key, int delta, long initial, int exp) { + public ArcusFuture decr(String key, int delta, long initial, long exp) { if (initial < 0) { throw new IllegalArgumentException("Initial value must be 0 or greater."); } return mutate(Mutator.decr, key, delta, initial, exp); } - private ArcusFuture mutate(Mutator mutator, String key, int delta, long initial, int exp) { + private ArcusFuture mutate(Mutator mutator, String key, int delta, long initial, long exp) { if (delta <= 0) { throw new IllegalArgumentException("Delta must be greater than 0."); } @@ -713,14 +713,13 @@ public ArcusFuture> multiDelete(List keys) { @Override public ArcusFuture lopCreate(String key, ElementValueType type, - CollectionAttributes attributes) { + CreateAttributes attributes) { if (attributes == null) { throw new IllegalArgumentException("CollectionAttributes cannot be null"); } ListCreate create = new ListCreate(TranscoderUtils.examineFlags(type), - attributes.getExpireTime(), attributes.getMaxCount(), - attributes.getOverflowAction(), attributes.getReadable(), false); + attributes, false); return collectionCreate(key, create); } @@ -731,7 +730,7 @@ public ArcusFuture lopInsert(String key, int index, T value) { @Override public ArcusFuture lopInsert(String key, int index, T value, - CollectionAttributes attributes) { + CreateAttributes attributes) { ListInsert insert = new ListInsert<>(value, null, attributes); return collectionInsert(key, String.valueOf(index), insert); } @@ -843,14 +842,13 @@ public ArcusFuture lopDelete(String key, int from, int to, boolean drop @Override public ArcusFuture sopCreate(String key, ElementValueType type, - CollectionAttributes attributes) { + CreateAttributes attributes) { if (attributes == null) { throw new IllegalArgumentException("CollectionAttributes cannot be null"); } - SetCreate create = new SetCreate( - TranscoderUtils.examineFlags(type), attributes.getExpireTime(), - attributes.getMaxCount(), attributes.getReadable(), false); + SetCreate create = new SetCreate(TranscoderUtils.examineFlags(type), + attributes, false); return collectionCreate(key, create); } @@ -860,7 +858,7 @@ public ArcusFuture sopInsert(String key, T value) { } @Override - public ArcusFuture sopInsert(String key, T value, CollectionAttributes attributes) { + public ArcusFuture sopInsert(String key, T value, CreateAttributes attributes) { SetInsert insert = new SetInsert<>(value, null, attributes); return collectionInsert(key, "", insert); } @@ -963,14 +961,13 @@ public ArcusFuture sopDelete(String key, T value, boolean dropIfEmpty) @Override public ArcusFuture mopCreate(String key, ElementValueType type, - CollectionAttributes attributes) { + CreateAttributes attributes) { if (attributes == null) { throw new IllegalArgumentException("CollectionAttributes cannot be null"); } MapCreate create = new MapCreate(TranscoderUtils.examineFlags(type), - attributes.getExpireTime(), attributes.getMaxCount(), - attributes.getReadable(), false); + attributes, false); return collectionCreate(key, create); } @@ -981,7 +978,7 @@ public ArcusFuture mopInsert(String key, String mKey, T value) { @Override public ArcusFuture mopInsert(String key, String mKey, T value, - CollectionAttributes attributes) { + CreateAttributes attributes) { keyValidator.validateMKey(mKey); MapInsert insert = new MapInsert<>(value, null, attributes); @@ -995,7 +992,7 @@ public ArcusFuture mopUpsert(String key, String mKey, T value) { @Override public ArcusFuture mopUpsert(String key, String mKey, T value, - CollectionAttributes attributes) { + CreateAttributes attributes) { keyValidator.validateMKey(mKey); MapUpsert upsert = new MapUpsert<>(value, attributes); @@ -1145,14 +1142,13 @@ public ArcusFuture mopDelete(String key, List mKeys, boolean dr @Override public ArcusFuture bopCreate(String key, ElementValueType type, - CollectionAttributes attributes) { + CreateAttributes attributes) { if (attributes == null) { throw new IllegalArgumentException("CollectionAttributes cannot be null"); } CollectionCreate create = new BTreeCreate(TranscoderUtils.examineFlags(type), - attributes.getExpireTime(), attributes.getMaxCount(), - attributes.getOverflowAction(), attributes.getReadable(), false); + attributes, false); return collectionCreate(key, create); } @@ -1164,7 +1160,7 @@ public ArcusFuture bopInsert(String key, BTreeElement element) { @Override public ArcusFuture bopInsert(String key, BTreeElement element, - CollectionAttributes attributes) { + CreateAttributes attributes) { BTreeInsert insert = new BTreeInsert<>(element.getValue(), element.getEFlag(), null, attributes); return collectionInsert(key, element.getBKey().toString(), insert); @@ -1178,7 +1174,7 @@ public ArcusFuture>> bopInsertAndGetTrimmed( @Override public ArcusFuture>> bopInsertAndGetTrimmed( - String key, BTreeElement element, CollectionAttributes attributes) { + String key, BTreeElement element, CreateAttributes attributes) { return bopInsertOrUpsertAndGetTrimmed(key, element, false, attributes); } @@ -1189,7 +1185,7 @@ public ArcusFuture bopUpsert(String key, BTreeElement element) { @Override public ArcusFuture bopUpsert(String key, BTreeElement element, - CollectionAttributes attributes) { + CreateAttributes attributes) { BTreeUpsert upsert = new BTreeUpsert<>(element.getValue(), element.getEFlag(), null, attributes); return collectionInsert(key, element.getBKey().toString(), upsert); @@ -1203,12 +1199,12 @@ public ArcusFuture>> bopUpsertAndGetTrimmed( @Override public ArcusFuture>> bopUpsertAndGetTrimmed( - String key, BTreeElement element, CollectionAttributes attributes) { + String key, BTreeElement element, CreateAttributes attributes) { return bopInsertOrUpsertAndGetTrimmed(key, element, true, attributes); } private ArcusFutureImpl>> bopInsertOrUpsertAndGetTrimmed( - String key, BTreeElement element, boolean isUpsert, CollectionAttributes attributes) { + String key, BTreeElement element, boolean isUpsert, CreateAttributes attributes) { AbstractArcusResult>> result = new AbstractArcusResult<>(new AtomicReference<>()); ArcusFutureImpl>> future = new ArcusFutureImpl<>(result); @@ -1267,7 +1263,7 @@ public void gotData(int flags, BKeyObject bKeyObject, byte[] eFlag, byte[] data) private static BTreeInsertAndGet createBTreeInsertAndGet(BTreeElement element, boolean isUpsert, - CollectionAttributes attributes) { + CreateAttributes attributes) { if (element.getBKey().getType() == BKey.BKeyType.LONG) { return new BTreeInsertAndGet<>((long) element.getBKey().getData(), element.getEFlag(), element.getValue(), isUpsert, attributes); diff --git a/src/main/java/net/spy/memcached/v2/AsyncArcusCommandsIF.java b/src/main/java/net/spy/memcached/v2/AsyncArcusCommandsIF.java index 3c93c5314..3e67f38da 100644 --- a/src/main/java/net/spy/memcached/v2/AsyncArcusCommandsIF.java +++ b/src/main/java/net/spy/memcached/v2/AsyncArcusCommandsIF.java @@ -24,7 +24,7 @@ import net.spy.memcached.CASValue; import net.spy.memcached.collection.BTreeOrder; -import net.spy.memcached.collection.CollectionAttributes; +import net.spy.memcached.collection.CreateAttributes; import net.spy.memcached.collection.ElementFlagFilter; import net.spy.memcached.collection.ElementValueType; import net.spy.memcached.v2.vo.BKey; @@ -49,7 +49,7 @@ public interface AsyncArcusCommandsIF { * @param value the value to store * @return {@code true} if stored, otherwise {@code false} */ - ArcusFuture set(String key, int exp, T value); + ArcusFuture set(String key, long exp, T value); /** * Add a value for the given key if it does not exist. @@ -59,7 +59,7 @@ public interface AsyncArcusCommandsIF { * @param value the value to store * @return {@code true} if stored, otherwise {@code false} */ - ArcusFuture add(String key, int exp, T value); + ArcusFuture add(String key, long exp, T value); /** * Replace a value for the given key if it exists. @@ -69,7 +69,7 @@ public interface AsyncArcusCommandsIF { * @param value the value to store * @return {@code true} if stored, otherwise {@code false} */ - ArcusFuture replace(String key, int exp, T value); + ArcusFuture replace(String key, long exp, T value); /** * Sets multiple key-value pairs. @@ -78,7 +78,7 @@ public interface AsyncArcusCommandsIF { * @param exp expiration time in seconds * @return Map of key to Boolean result */ - ArcusFuture> multiSet(Map items, int exp); + ArcusFuture> multiSet(Map items, long exp); /** * Add multiple key-value pairs if they do not exist. @@ -87,7 +87,7 @@ public interface AsyncArcusCommandsIF { * @param exp expiration time in seconds * @return Map of key to Boolean result */ - ArcusFuture> multiAdd(Map items, int exp); + ArcusFuture> multiAdd(Map items, long exp); /** * Replace multiple key-value pairs if they exist. @@ -96,7 +96,7 @@ public interface AsyncArcusCommandsIF { * @param exp expiration time in seconds * @return Map of key to Boolean result */ - ArcusFuture> multiReplace(Map items, int exp); + ArcusFuture> multiReplace(Map items, long exp); /** * Prepend String or byte[] to an existing same type of value. @@ -126,7 +126,7 @@ public interface AsyncArcusCommandsIF { * @return {@code true} if compared and set successfully, * {@code false} if the key does not exist or CAS ID does not match */ - ArcusFuture cas(String key, int exp, T value, long casId); + ArcusFuture cas(String key, long exp, T value, long casId); /** * Increments a numeric value stored at the given key by {@code delta}. @@ -148,7 +148,7 @@ public interface AsyncArcusCommandsIF { * @param exp expiration time in seconds, applied only when a new key is created * @return the new value after increment, or {@code initial} if the key did not exist */ - ArcusFuture incr(String key, int delta, long initial, int exp); + ArcusFuture incr(String key, int delta, long initial, long exp); /** * Decrements a numeric value stored at the given key by {@code delta}. @@ -172,7 +172,7 @@ public interface AsyncArcusCommandsIF { * @param exp expiration time in seconds, applied only when a new key is created * @return the new value after decrement, or {@code initial} if the key did not exist */ - ArcusFuture decr(String key, int delta, long initial, int exp); + ArcusFuture decr(String key, int delta, long initial, long exp); /** * Get a value for the given key. @@ -233,13 +233,12 @@ public interface AsyncArcusCommandsIF { * @return {@code true} if created, {@code false} if the key already exists */ ArcusFuture lopCreate(String key, ElementValueType type, - CollectionAttributes attributes); + CreateAttributes attributes); /** * Insert an element at the given index into a list. * Negative indexes are counted backward from the end of the list. * - * * @param key key of the list * @param index index at which to insert the element * @param value the value to insert @@ -258,7 +257,7 @@ ArcusFuture lopCreate(String key, ElementValueType type, * @param attributes attributes to use when creating the list, or {@code null} to not create * @return {@code true} if the element was inserted, {@code null} if the key is not found */ - ArcusFuture lopInsert(String key, int index, T value, CollectionAttributes attributes); + ArcusFuture lopInsert(String key, int index, T value, CreateAttributes attributes); /** * Get an element at the given index from a list. @@ -318,7 +317,7 @@ ArcusFuture lopCreate(String key, ElementValueType type, * @return {@code true} if created, {@code false} if the key already exists */ ArcusFuture sopCreate(String key, ElementValueType type, - CollectionAttributes attributes); + CreateAttributes attributes); /** * Insert an element into a set. @@ -342,7 +341,7 @@ ArcusFuture sopCreate(String key, ElementValueType type, * {@code false} if the element already exists, * {@code null} if the key is not found */ - ArcusFuture sopInsert(String key, T value, CollectionAttributes attributes); + ArcusFuture sopInsert(String key, T value, CreateAttributes attributes); /** * Get elements randomly from a set. @@ -387,7 +386,7 @@ ArcusFuture sopCreate(String key, ElementValueType type, * @return {@code true} if created, {@code false} if the key already exists */ ArcusFuture mopCreate(String key, ElementValueType type, - CollectionAttributes attributes); + CreateAttributes attributes); /** * Insert an element with the given mKey into a map. @@ -413,7 +412,7 @@ ArcusFuture mopCreate(String key, ElementValueType type, * {@code false} if the mKey already exists, * {@code null} if the key is not found */ - ArcusFuture mopInsert(String key, String mKey, T value, CollectionAttributes attributes); + ArcusFuture mopInsert(String key, String mKey, T value, CreateAttributes attributes); /** * Upsert an element with the given mKey in a map. @@ -437,7 +436,7 @@ ArcusFuture mopCreate(String key, ElementValueType type, * @param attributes attributes to use when creating the map * @return {@code true} if upserted, {@code null} if the key is not found */ - ArcusFuture mopUpsert(String key, String mKey, T value, CollectionAttributes attributes); + ArcusFuture mopUpsert(String key, String mKey, T value, CreateAttributes attributes); /** * Update the value of an element with the given mKey in a map. @@ -529,7 +528,7 @@ ArcusFuture mopCreate(String key, ElementValueType type, * @return {@code true} if created, otherwise {@code false} */ ArcusFuture bopCreate(String key, ElementValueType type, - CollectionAttributes attributes); + CreateAttributes attributes); /** * Insert an element into a btree item. @@ -553,7 +552,7 @@ ArcusFuture bopCreate(String key, ElementValueType type, * {@code null} if key is not found */ ArcusFuture bopInsert(String key, BTreeElement element, - CollectionAttributes attributes); + CreateAttributes attributes); /** * Insert an element into a btree item and get trimmed element if overflow trim occurs. @@ -574,7 +573,7 @@ ArcusFuture>> bopInsertAndGetTrimmed( * @return {@code Map.Entry} with insertion result and trimmed element */ ArcusFuture>> bopInsertAndGetTrimmed( - String key, BTreeElement element, CollectionAttributes attributes); + String key, BTreeElement element, CreateAttributes attributes); /** * Upsert an element into a btree item. @@ -594,7 +593,7 @@ ArcusFuture>> bopInsertAndGetTrimmed( * @return {@code true} if upserted, {@code null} if the key is not found */ ArcusFuture bopUpsert(String key, BTreeElement element, - CollectionAttributes attributes); + CreateAttributes attributes); /** * Upsert an element into a btree item and get trimmed element if overflow trim occurs. @@ -615,7 +614,7 @@ ArcusFuture>> bopUpsertAndGetTrimmed( * @return {@code Map.Entry} with upsertion result and trimmed element */ ArcusFuture>> bopUpsertAndGetTrimmed( - String key, BTreeElement element, CollectionAttributes attributes); + String key, BTreeElement element, CreateAttributes attributes); /** * Update an element in a btree item diff --git a/src/main/java/net/spy/memcached/v2/attribute/ItemAttributes.java b/src/main/java/net/spy/memcached/v2/attribute/ItemAttributes.java new file mode 100644 index 000000000..fb169d6c8 --- /dev/null +++ b/src/main/java/net/spy/memcached/v2/attribute/ItemAttributes.java @@ -0,0 +1,123 @@ +package net.spy.memcached.v2.attribute; + +import net.spy.memcached.collection.BKeyObject; +import net.spy.memcached.collection.CollectionOverflowAction; +import net.spy.memcached.collection.CollectionType; +import net.spy.memcached.compat.SpyObject; +import net.spy.memcached.util.BTreeUtil; +import net.spy.memcached.v2.vo.BKey; + +/** + * Result of a {@code getAttributes} (getattr) call in the v2 API. Read-only. + * + *

{@code expireTime} is exposed as {@code long}. The server returns the + * remaining relative seconds, which always fits in {@code int} range, but the + * type is kept as {@code Long} for consistency with the v2 write side. + */ +public class ItemAttributes extends SpyObject { + + private Integer flags; + private Long expireTime; + private CollectionType type; + private Long count; + private Long maxCount; + private CollectionOverflowAction overflowAction; + private Boolean readable; + private BKey maxBKeyRange; + private BKey minBKey; + private BKey maxBKey; + private Long trimmed; + + public void setAttribute(String attribute) { + String[] split = attribute.split("="); + if (split.length != 2) { + return; + } + String name = split[0]; + String value = split[1]; + + try { + if ("flags".equals(name)) { + flags = Integer.parseInt(value); + } else if ("expiretime".equals(name)) { + expireTime = Long.parseLong(value); + } else if ("type".equals(name)) { + type = CollectionType.find(value); + } else if ("count".equals(name)) { + count = Long.parseLong(value); + } else if ("maxcount".equals(name)) { + maxCount = Long.parseLong(value); + } else if ("overflowaction".equals(name)) { + overflowAction = CollectionOverflowAction.valueOf(value); + } else if ("readable".equals(name)) { + readable = "on".equals(value); + } else if ("maxbkeyrange".equals(name)) { + maxBKeyRange = parseBKey(value); + } else if ("minbkey".equals(name)) { + if (!value.startsWith("-1")) { + minBKey = parseBKey(value); + } + } else if ("maxbkey".equals(name)) { + if (!value.startsWith("-1")) { + maxBKey = parseBKey(value); + } + } else if ("trimmed".equals(name)) { + trimmed = Long.parseLong(value); + } + } catch (Exception e) { + getLogger().info(e, e); + } + } + + private static BKey parseBKey(String value) { + if (value.startsWith("0x")) { + return BKey.of(new BKeyObject(BTreeUtil.hexStringToByteArrays(value.substring(2)))); + } + return BKey.of(new BKeyObject(Long.parseLong(value))); + } + + public Integer getFlags() { + return flags; + } + + public Long getExpireTime() { + return expireTime; + } + + public CollectionType getType() { + return type; + } + + public Long getCount() { + return count; + } + + public Long getMaxCount() { + return maxCount; + } + + public CollectionOverflowAction getOverflowAction() { + return overflowAction; + } + + public Boolean getReadable() { + return readable; + } + + public BKey getMaxBKeyRange() { + return maxBKeyRange; + } + + public BKey getMinBKey() { + return minBKey; + } + + public BKey getMaxBKey() { + return maxBKey; + } + + public Long getTrimmed() { + return trimmed; + } + +} diff --git a/src/main/java/net/spy/memcached/v2/attribute/UpdateAttributes.java b/src/main/java/net/spy/memcached/v2/attribute/UpdateAttributes.java new file mode 100644 index 000000000..d3c4fdeb5 --- /dev/null +++ b/src/main/java/net/spy/memcached/v2/attribute/UpdateAttributes.java @@ -0,0 +1,98 @@ + +package net.spy.memcached.v2.attribute; + +import net.spy.memcached.collection.CollectionOverflowAction; +import net.spy.memcached.collection.SetAttributes; +import net.spy.memcached.v2.vo.BKey; + +/** + * Attributes to set on an existing collection via {@code setAttributes} (v2). + * + *

Fields are nullable: only fields explicitly set are sent, leaving the + * others unchanged on the server (partial update). {@code expireTime} is a + * {@code long}, so Unix timestamps beyond the {@code int} range are supported. + * {@code maxBkeyRange} is a b+tree-only attribute expressed as a v2 {@link BKey}. + */ +public final class UpdateAttributes implements SetAttributes { + + private final String clause; + + private UpdateAttributes(Builder builder) { + StringBuilder b = new StringBuilder(); + if (builder.expTime != null) { + b.append(" expiretime=").append(builder.expTime); + } + if (builder.maxCount != null) { + b.append(" maxcount=").append(builder.maxCount); + } + if (builder.overflowAction != null) { + b.append(" overflowaction=").append(builder.overflowAction); + } + if (builder.readable != null) { + b.append(" readable=").append(builder.readable ? "on" : "off"); + } + if (builder.maxBKeyRange != null) { + b.append(" maxbkeyrange=").append(builder.maxBKeyRange); + } + this.clause = (b.length() < 1) ? "" : b.substring(1); + } + + public static Builder builder() { + return new Builder(); + } + + @Override + public String stringify() { + return clause; + } + + @Override + public int getLength() { + return clause.length(); + } + + public static final class Builder { + private Long expTime; + private Long maxCount; + private CollectionOverflowAction overflowAction; + private Boolean readable; + private BKey maxBKeyRange; + + private Builder() { + } + + public Builder expireTime(long expireTime) { + this.expTime = expireTime; + return this; + } + + public Builder maxCount(long maxCount) { + this.maxCount = maxCount; + return this; + } + + public Builder overflowAction(CollectionOverflowAction overflowAction) { + this.overflowAction = overflowAction; + return this; + } + + public Builder readable(boolean readable) { + this.readable = readable; + return this; + } + + public Builder maxBKeyRange(BKey maxBKeyRange) { + this.maxBKeyRange = maxBKeyRange; + return this; + } + + public UpdateAttributes build() { + UpdateAttributes attributes = new UpdateAttributes(this); + if (attributes.getLength() == 0) { + throw new IllegalArgumentException("At least one attribute must be set."); + } + + return attributes; + } + } +} diff --git a/src/test/java/net/spy/memcached/collection/CreateAttributesTest.java b/src/test/java/net/spy/memcached/collection/CreateAttributesTest.java new file mode 100644 index 000000000..beed32aea --- /dev/null +++ b/src/test/java/net/spy/memcached/collection/CreateAttributesTest.java @@ -0,0 +1,38 @@ +package net.spy.memcached.collection; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class CreateAttributesTest { + + @Test + void builderDefaults() { + CreateAttributes attributes = CreateAttributes.builder().build(); + assertEquals(0L, attributes.getExpireTime()); + assertEquals(4_000L, attributes.getMaxCount()); + assertNull(attributes.getOverflowAction()); + assertTrue(attributes.getReadable()); + } + + @Test + void ofNullReturnsNull() { + assertNull(CreateAttributes.of(null)); + } + + @Test + void ofCopyValues() { + CollectionAttributes prevAttr + = new CollectionAttributes(60, 1_000L, CollectionOverflowAction.error); + prevAttr.setReadable(false); + + CreateAttributes newAttr = CreateAttributes.of(prevAttr); + assertEquals(60L, newAttr.getExpireTime()); + assertEquals(1_000L, newAttr.getMaxCount()); + assertEquals(CollectionOverflowAction.error, newAttr.getOverflowAction()); + assertFalse(newAttr.getReadable()); + } +} diff --git a/src/test/java/net/spy/memcached/v2/BTreeAsyncArcusCommandsTest.java b/src/test/java/net/spy/memcached/v2/BTreeAsyncArcusCommandsTest.java index a356f70b6..8ec2959f5 100644 --- a/src/test/java/net/spy/memcached/v2/BTreeAsyncArcusCommandsTest.java +++ b/src/test/java/net/spy/memcached/v2/BTreeAsyncArcusCommandsTest.java @@ -8,8 +8,8 @@ import java.util.stream.Collectors; import net.spy.memcached.collection.BTreeOrder; -import net.spy.memcached.collection.CollectionAttributes; import net.spy.memcached.collection.CollectionOverflowAction; +import net.spy.memcached.collection.CreateAttributes; import net.spy.memcached.collection.ElementFlagFilter; import net.spy.memcached.collection.ElementFlagUpdate; import net.spy.memcached.collection.ElementValueType; @@ -55,7 +55,7 @@ void bopInsert() throws Exception { String key = keys.get(0); // when - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopInsert(key, ELEMENTS.get(0)); @@ -73,7 +73,7 @@ void bopInsertDifferentTypeAndGetDifferentElement() throws Exception { BTreeElement element = ELEMENTS.get(0); // when - async.bopCreate(key, ElementValueType.LONG, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.LONG, CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopInsert(key, element); @@ -102,7 +102,7 @@ void bopInsertNotFound() throws Exception { void bopInsertTypeMisMatch() throws Exception { // given String key = keys.get(0); - CollectionAttributes attrs = new CollectionAttributes(); + CreateAttributes attrs = CreateAttributes.DEFAULT; // when async.set(key, 0, VALUE) @@ -124,8 +124,9 @@ void bopInsertTypeMisMatch() throws Exception { void bopInsertAndGetTrimmed() throws Exception { // given String key = keys.get(0); - CollectionAttributes attrs = new CollectionAttributes(); - attrs.setMaxCount(3); + CreateAttributes attrs = CreateAttributes.builder() + .maxCount(3) + .build(); // when async.bopInsert(key, ELEMENTS.get(0), attrs) @@ -147,8 +148,9 @@ void bopInsertAndGetTrimmed() throws Exception { void bopFailToInsertAndGetTrimmed() throws Exception { // given String key = keys.get(0); - CollectionAttributes attrs = new CollectionAttributes(); - attrs.setMaxCount(3); + CreateAttributes attrs = CreateAttributes.builder() + .maxCount(3) + .build(); // when async.bopInsert(key, ELEMENTS.get(0), attrs) @@ -168,8 +170,9 @@ void bopFailToInsertAndGetTrimmed() throws Exception { void bopUpsertAndGetTrimmed() throws Exception { // given String key = keys.get(0); - CollectionAttributes attrs = new CollectionAttributes(); - attrs.setMaxCount(3); + CreateAttributes attrs = CreateAttributes.builder() + .maxCount(3) + .build(); // when async.bopInsert(key, ELEMENTS.get(0), attrs) @@ -190,8 +193,9 @@ void bopUpsertAndGetTrimmed() throws Exception { void bopUpsertAndNotGetTrimmed() throws Exception { // given String key = keys.get(0); - CollectionAttributes attrs = new CollectionAttributes(); - attrs.setMaxCount(3); + CreateAttributes attrs = CreateAttributes.builder() + .maxCount(3) + .build(); String newValue = "new_value"; // when @@ -213,7 +217,7 @@ void bopUpsertAndNotGetTrimmed() throws Exception { void bopGet() throws Exception { // given String key = keys.get(0); - CollectionAttributes attrs = new CollectionAttributes(); + CreateAttributes attrs = CreateAttributes.DEFAULT; // when async.bopInsert(key, ELEMENTS.get(0), attrs) @@ -237,7 +241,7 @@ void bopGet() throws Exception { void bopGetWithDelete() throws Exception { // given String key = keys.get(0); - CollectionAttributes attrs = new CollectionAttributes(); + CreateAttributes attrs = CreateAttributes.DEFAULT; BopGetArgs getArgsWithDelete = new BopGetArgs(ElementFlagFilter.DO_NOT_FILTER, GetMode.DELETE); @@ -267,7 +271,7 @@ void bopGetWithDeleteAndDropIfEmpty() throws Exception { BopGetArgs getArgsWithDrop = new BopGetArgs(ElementFlagFilter.DO_NOT_FILTER, GetMode.DROP); // when - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenCompose(result -> async.bopGet(key, BKey.of(1L), getArgsWithDrop)) // then .thenAccept(element -> assertEquals(ELEMENTS.get(0), element)) @@ -296,7 +300,7 @@ void bopGetRangeNotExistElements() throws Exception { String key = keys.get(0); // when - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenCompose(result -> async.bopInsert(key, ELEMENTS.get(1))) .thenCompose(result -> async.bopInsert(key, ELEMENTS.get(2))) .thenCompose(result -> async.bopGet(key, @@ -315,7 +319,7 @@ void bopGetRangeNotExistElements() throws Exception { void bopGetRangeWithDelete() throws Exception { // given String key = keys.get(0); - CollectionAttributes attrs = new CollectionAttributes(); + CreateAttributes attrs = CreateAttributes.DEFAULT; BopRangeGetArgs getArgsWithDelete = new BopRangeGetArgs(ElementFlagFilter.DO_NOT_FILTER, 0, 10, GetMode.DELETE); @@ -347,7 +351,7 @@ void bopGetRangeDescending() throws Exception { String key = keys.get(0); // when - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenCompose(result -> async.bopInsert(key, ELEMENTS.get(1))) .thenCompose(result -> async.bopInsert(key, ELEMENTS.get(2))) .thenCompose(result -> async.bopInsert(key, ELEMENTS.get(3))) @@ -369,7 +373,7 @@ void bopGetRangeDescending() throws Exception { void bopMultiGet() throws Exception { // given List testKeys = Arrays.asList(keys.get(0), keys.get(1), keys.get(2)); - CollectionAttributes attr = new CollectionAttributes(); + CreateAttributes attr = CreateAttributes.DEFAULT; // when async.bopInsert(testKeys.get(0), ELEMENTS.get(0), attr) @@ -405,7 +409,7 @@ void bopMultiGet() throws Exception { void bopMultiGetDescending() throws Exception { // given List testKeys = Arrays.asList(keys.get(0), keys.get(1), keys.get(2)); - CollectionAttributes attr = new CollectionAttributes(); + CreateAttributes attr = CreateAttributes.DEFAULT; // when async.bopInsert(testKeys.get(0), ELEMENTS.get(0), attr) @@ -446,7 +450,7 @@ void bopMultiGetDescending() throws Exception { void bopMultiGetNotFoundElement() throws Exception { // given List testKeys = Arrays.asList(keys.get(0), keys.get(1)); - CollectionAttributes attrs = new CollectionAttributes(); + CreateAttributes attrs = CreateAttributes.DEFAULT; // when async.bopInsert(testKeys.get(0), ELEMENTS.get(0), attrs) @@ -472,7 +476,7 @@ void bopMultiGetNotFoundElement() throws Exception { void bopSortMergeGetAscendingUnique() throws Exception { // given List testKeys = Arrays.asList(keys.get(0), keys.get(1), keys.get(2)); - CollectionAttributes attrs = new CollectionAttributes(); + CreateAttributes attrs = CreateAttributes.DEFAULT; BopSMGetArgs getArgs = new BopSMGetArgs(ElementFlagFilter.DO_NOT_FILTER, 1000, true); async.bopInsert(testKeys.get(0), ELEMENTS.get(0), attrs) @@ -507,7 +511,7 @@ void bopSortMergeGetAscendingUnique() throws Exception { void bopSortMergeGetDescendingUnique() throws Exception { // given List testKeys = Arrays.asList(keys.get(0), keys.get(1), keys.get(2)); - CollectionAttributes attrs = new CollectionAttributes(); + CreateAttributes attrs = CreateAttributes.DEFAULT; BopSMGetArgs getArgs = new BopSMGetArgs(ElementFlagFilter.DO_NOT_FILTER, 1000, true); async.bopInsert(testKeys.get(0), ELEMENTS.get(0), attrs) @@ -542,7 +546,7 @@ void bopSortMergeGetDescendingUnique() throws Exception { void bopSortMergeGetAscendingDuplicated() throws Exception { // given List testKeys = Arrays.asList(keys.get(0), keys.get(1)); - CollectionAttributes attrs = new CollectionAttributes(); + CreateAttributes attrs = CreateAttributes.DEFAULT; async.bopInsert(testKeys.get(0), ELEMENTS.get(0), attrs) .thenCompose(result -> async.bopInsert(testKeys.get(0), ELEMENTS.get(1))) @@ -580,7 +584,7 @@ void bopSortMergeGetAscendingDuplicated() throws Exception { void bopSortMergeGetDescendingDuplicated() throws Exception { // given List testKeys = Arrays.asList(keys.get(0), keys.get(1)); - CollectionAttributes attrs = new CollectionAttributes(); + CreateAttributes attrs = CreateAttributes.DEFAULT; async.bopInsert(testKeys.get(0), ELEMENTS.get(0), attrs) .thenCompose(result -> async.bopInsert(testKeys.get(0), ELEMENTS.get(1))) @@ -617,7 +621,7 @@ void bopSortMergeGetDescendingDuplicated() throws Exception { @Test void bopSortMergeGetUnique() throws Exception { // given - CollectionAttributes attrs = new CollectionAttributes(); + CreateAttributes attrs = CreateAttributes.DEFAULT; BopSMGetArgs getArgs = new BopSMGetArgs(ElementFlagFilter.DO_NOT_FILTER, 1000, true); async.bopInsert(keys.get(0), ELEMENTS.get(0), attrs) @@ -644,7 +648,7 @@ void bopSortMergeGetUnique() throws Exception { void bopSortMergeGetWithMissedKeys() throws Exception { // given List testKeys = Arrays.asList(keys.get(0), keys.get(1)); - CollectionAttributes attrs = new CollectionAttributes(); + CreateAttributes attrs = CreateAttributes.DEFAULT; async.bopInsert(testKeys.get(0), ELEMENTS.get(0), attrs) // when @@ -693,7 +697,7 @@ void bopSortMergeGetNotFound() throws Exception { void bopSortMergeGetNotFoundElement() throws Exception { // given List testKeys = Arrays.asList(keys.get(0), keys.get(1), keys.get(2)); - CollectionAttributes attrs = new CollectionAttributes(); + CreateAttributes attrs = CreateAttributes.DEFAULT; // when async.bopInsert(testKeys.get(0), ELEMENTS.get(0), attrs) @@ -720,8 +724,9 @@ void bopSortMergeGetNotFoundElement() throws Exception { void bopSortMergeGetWithTrimmedKeys() throws Exception { // given List testKeys = Arrays.asList(keys.get(0), keys.get(1), keys.get(2)); - CollectionAttributes attrs = new CollectionAttributes(); - attrs.setMaxCount(2); + CreateAttributes attrs = CreateAttributes.builder() + .maxCount(2) + .build(); // when async.bopInsert(testKeys.get(0), ELEMENTS.get(0), attrs) @@ -761,8 +766,9 @@ void bopSortMergeGetWithTrimmedKeys() throws Exception { void bopSortMergeGetNotHaveTrimmedKeysOutOfElementsRangeDescending() throws Exception { // given List testKeys = Arrays.asList(keys.get(0), keys.get(1)); - CollectionAttributes attrs = new CollectionAttributes(); - attrs.setMaxCount(2); + CreateAttributes attrs = CreateAttributes.builder() + .maxCount(2) + .build(); // when async.bopInsert(testKeys.get(0), ELEMENTS.get(0), attrs) // to be trimmed @@ -798,9 +804,10 @@ void bopSortMergeGetNotHaveTrimmedKeysOutOfElementsRangeDescending() throws Exce void bopSortMergeGetNotHaveTrimmedKeysOutOfElementsRangeAscending() throws Exception { // given List testKeys = Arrays.asList(keys.get(0), keys.get(1)); - CollectionAttributes attrs = new CollectionAttributes(); - attrs.setMaxCount(2); - attrs.setOverflowAction(CollectionOverflowAction.largest_trim); + CreateAttributes attrs = CreateAttributes.builder() + .maxCount(2) + .overflowAction(CollectionOverflowAction.largest_trim) + .build(); // when async.bopInsert(testKeys.get(0), ELEMENTS.get(3), attrs) @@ -837,7 +844,7 @@ void bopUpdateSuccess() throws ExecutionException, InterruptedException, Timeout // given String key = keys.get(0); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopGet(key, BKey.of(1L), BopGetArgs.DEFAULT); @@ -877,7 +884,7 @@ void bopUpdateValueSuccess() throws ExecutionException, InterruptedException, Ti // given String key = keys.get(0); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -907,7 +914,7 @@ void bopUpdateEFlagSuccess() throws ExecutionException, InterruptedException, Ti // given String key = keys.get(0); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -940,7 +947,7 @@ void bopUpdateNotFoundElement() throws ExecutionException, InterruptedException, // given String key = keys.get(0); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -981,7 +988,7 @@ void bopIncrSuccess() throws ExecutionException, InterruptedException, TimeoutEx BKey bKey = BKey.of(1L); BTreeElement element = new BTreeElement<>(bKey, "100", null); - async.bopInsert(key, element, new CollectionAttributes()) + async.bopInsert(key, element, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1014,7 +1021,7 @@ void bopIncrNotFoundElement() throws ExecutionException, InterruptedException, T String key = keys.get(0); BKey bKey = BKey.of(999L); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1034,7 +1041,7 @@ void bopIncrInitialNotExistsElement() throws ExecutionException, InterruptedExce String key = keys.get(0); BKey bKey = BKey.of(999L); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1063,7 +1070,7 @@ void bopIncrInitialExistingElement() throws ExecutionException, InterruptedExcep BKey bKey = BKey.of(1L); BTreeElement element = new BTreeElement<>(bKey, "100", null); - async.bopInsert(key, element, new CollectionAttributes()) + async.bopInsert(key, element, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1104,7 +1111,7 @@ void bopIncrBKeyMismatch() throws ExecutionException, InterruptedException, Time // given String key = keys.get(0); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1128,7 +1135,7 @@ void bopDecrSuccess() throws ExecutionException, InterruptedException, TimeoutEx BKey bKey = BKey.of(1L); BTreeElement element = new BTreeElement<>(bKey, "100", null); - async.bopInsert(key, element, new CollectionAttributes()) + async.bopInsert(key, element, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1161,7 +1168,7 @@ void bopDecrNotFoundElement() throws ExecutionException, InterruptedException, T String key = keys.get(0); BKey bKey = BKey.of(999L); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1181,7 +1188,7 @@ void bopDecrInitialNotExistsElement() throws ExecutionException, InterruptedExce String key = keys.get(0); BKey bKey = BKey.of(999L); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1202,7 +1209,7 @@ void bopDecrInitialExistingElement() throws ExecutionException, InterruptedExcep BKey bKey = BKey.of(1L); BTreeElement element = new BTreeElement<>(bKey, "100", null); - async.bopInsert(key, element, new CollectionAttributes()) + async.bopInsert(key, element, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1222,7 +1229,7 @@ void bopDecrResultUnderZero() throws ExecutionException, InterruptedException, T BKey bKey = BKey.of(1L); BTreeElement element = new BTreeElement<>(bKey, "5", null); - async.bopInsert(key, element, new CollectionAttributes()) + async.bopInsert(key, element, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1263,7 +1270,7 @@ void bopDecrBKeyMismatch() throws ExecutionException, InterruptedException, Time // given String key = keys.get(0); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1287,7 +1294,7 @@ void bopGetPositionSuccess() throws ExecutionException, InterruptedException, String key = keys.get(0); BKey bKey = ELEMENTS.get(1).getBKey(); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopInsert(key, ELEMENTS.get(0)); @@ -1332,7 +1339,7 @@ void bopGetPositionNotFoundElement() throws ExecutionException, InterruptedExcep String key = keys.get(0); BKey bKey = BKey.of(1L); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1375,7 +1382,7 @@ void bopGetByPositionSuccess() throws ExecutionException, InterruptedException, BKey bKey = BKey.of(1L); BTreeElement element = new BTreeElement<>(bKey, "value", null); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopInsert(key, element); @@ -1415,7 +1422,7 @@ void bopGetByPositionNotFoundElement() throws ExecutionException, InterruptedExc // given String key = keys.get(0); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1456,7 +1463,7 @@ void bopGetByPositionRangeSuccess() throws ExecutionException, InterruptedExcept // given String key = keys.get(0); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopInsert(key, ELEMENTS.get(0)); @@ -1507,7 +1514,7 @@ void bopGetByPositionRangeNotFoundElement() throws ExecutionException, Interrupt // given String key = keys.get(0); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1552,7 +1559,7 @@ void bopPositionWithGetSuccess() throws ExecutionException, InterruptedException String key = keys.get(0); BKey bKey = ELEMENTS.get(1).getBKey(); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopInsert(key, ELEMENTS.get(0)); @@ -1614,7 +1621,7 @@ void bopPositionWithGetNotFoundElement() throws ExecutionException, InterruptedE String key = keys.get(0); BKey bKey = BKey.of(999L); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopInsert(key, ELEMENTS.get(0)); @@ -1661,7 +1668,7 @@ void bopPositionWithGetBKeyMismatch() throws ExecutionException, InterruptedExce String key = keys.get(0); BKey bKey = BKey.of(new byte[]{0x01}); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1684,7 +1691,7 @@ void bopDeleteSuccess() throws ExecutionException, InterruptedException, Timeout String key = keys.get(0); BKey bKey = ELEMENTS.get(0).getBKey(); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1709,7 +1716,7 @@ void bopDeleteDropIfEmpty() throws ExecutionException, InterruptedException, Tim // given String key = keys.get(0); BKey bKey = ELEMENTS.get(0).getBKey(); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1747,7 +1754,7 @@ void bopDeleteNotFoundElement() throws ExecutionException, InterruptedException, String key = keys.get(0); BKey bKey = BKey.of(999L); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1788,7 +1795,7 @@ void bopDeleteBKeyMismatch() throws ExecutionException, InterruptedException, Ti String key = keys.get(0); BKey bKey = BKey.of(new byte[]{0x01}); - async.bopInsert(key, ELEMENTS.get(0) /* long BKey */, new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0) /* long BKey */, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1810,7 +1817,7 @@ void bopDeleteByRangeSuccess() throws ExecutionException, InterruptedException, String key = keys.get(0); BKey from = ELEMENTS.get(0).getBKey(); BKey to = ELEMENTS.get(2).getBKey(); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopInsert(key, ELEMENTS.get(1)); @@ -1843,7 +1850,7 @@ void bopDeleteByRangeCountZero() throws ExecutionException, InterruptedException String key = keys.get(0); BKey from = BKey.of(0L); BKey to = BKey.of(10L); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopInsert(key, ELEMENTS.get(1)); @@ -1885,7 +1892,7 @@ void bopDeleteByRangeEFlag() throws ExecutionException, InterruptedException, Ti BKey from = BKey.of(0L); BKey to = BKey.of(10L); - async.bopInsert(key, elementWithFlag, new CollectionAttributes()) + async.bopInsert(key, elementWithFlag, CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopInsert(key, elementWithoutFlag); @@ -1934,7 +1941,7 @@ void bopDeleteByRangeNotFoundElement() throws ExecutionException, InterruptedExc BKey from = BKey.of(100L); BKey to = BKey.of(200L); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -1979,7 +1986,7 @@ void bopDeleteByRangeBKeyMismatch() throws ExecutionException, InterruptedExcept BKey from = BKey.of(new byte[]{0x00}); BKey to = BKey.of(new byte[]{0x10}); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -2000,7 +2007,7 @@ void bopCountSuccess() throws ExecutionException, InterruptedException, TimeoutE // given String key = keys.get(0); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopInsert(key, ELEMENTS.get(1)); @@ -2033,7 +2040,7 @@ void bopCountEFlagFilter() throws ExecutionException, InterruptedException, Time BTreeElement elementWithFlag2 = new BTreeElement<>(BKey.of(2L), "value2", eFlag); BTreeElement elementWithoutFlag = new BTreeElement<>(BKey.of(3L), "value3", null); - async.bopInsert(key, elementWithFlag1, new CollectionAttributes()) + async.bopInsert(key, elementWithFlag1, CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.bopInsert(key, elementWithFlag2); @@ -2063,7 +2070,7 @@ void bopCountZero() throws ExecutionException, InterruptedException, TimeoutExce // given String key = keys.get(0); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -2124,7 +2131,7 @@ void bopCountBKeyMismatch() throws ExecutionException, InterruptedException, Tim // given String key = keys.get(0); - async.bopInsert(key, ELEMENTS.get(0), new CollectionAttributes()) + async.bopInsert(key, ELEMENTS.get(0), CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); diff --git a/src/test/java/net/spy/memcached/v2/KVAsyncArcusCommandsTest.java b/src/test/java/net/spy/memcached/v2/KVAsyncArcusCommandsTest.java index a4f42b737..b20ca4516 100644 --- a/src/test/java/net/spy/memcached/v2/KVAsyncArcusCommandsTest.java +++ b/src/test/java/net/spy/memcached/v2/KVAsyncArcusCommandsTest.java @@ -9,7 +9,7 @@ import java.util.concurrent.TimeoutException; import net.spy.memcached.CASValue; -import net.spy.memcached.collection.CollectionAttributes; +import net.spy.memcached.collection.CreateAttributes; import net.spy.memcached.collection.ElementValueType; import net.spy.memcached.ops.OperationException; @@ -722,7 +722,7 @@ void incrTypeMisMatchException() throws ExecutionException, InterruptedException // given String key = keys.get(0); - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.builder().build()) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -844,7 +844,7 @@ void decrTypeMismatchException() throws ExecutionException, InterruptedException String key = keys.get(0); // collection 타입 키를 생성해서 TypeMismatch 발생 - async.bopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.bopCreate(key, ElementValueType.STRING, CreateAttributes.builder().build()) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); diff --git a/src/test/java/net/spy/memcached/v2/ListAsyncArcusCommandsTest.java b/src/test/java/net/spy/memcached/v2/ListAsyncArcusCommandsTest.java index 22c448a0e..ccc383462 100644 --- a/src/test/java/net/spy/memcached/v2/ListAsyncArcusCommandsTest.java +++ b/src/test/java/net/spy/memcached/v2/ListAsyncArcusCommandsTest.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.concurrent.TimeUnit; -import net.spy.memcached.collection.CollectionAttributes; +import net.spy.memcached.collection.CreateAttributes; import net.spy.memcached.collection.ElementValueType; import net.spy.memcached.ops.OperationException; import net.spy.memcached.v2.vo.GetMode; @@ -28,7 +28,7 @@ void lopCreate() throws Exception { String key = keys.get(0); // when - async.lopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.lopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) // then .thenAccept(Assertions::assertTrue) .toCompletableFuture() @@ -40,13 +40,13 @@ void lopCreateAlreadyExists() throws Exception { // given String key = keys.get(0); - async.lopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.lopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); // when - async.lopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.lopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) // then .thenAccept(Assertions::assertFalse) .toCompletableFuture() @@ -58,7 +58,7 @@ void lopInsert() throws Exception { // given String key = keys.get(0); - async.lopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.lopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -88,7 +88,7 @@ void lopInsertWithAttributes() throws Exception { String key = keys.get(0); // when - async.lopInsert(key, 0, VALUES.get(0), new CollectionAttributes()) + async.lopInsert(key, 0, VALUES.get(0), CreateAttributes.DEFAULT) // then .thenCompose(result -> { assertTrue(result); @@ -110,7 +110,7 @@ void lopInsertTypeMismatch() throws Exception { .get(300L, TimeUnit.MILLISECONDS); // when - async.lopInsert(key, 0, VALUES.get(0), new CollectionAttributes()) + async.lopInsert(key, 0, VALUES.get(0), CreateAttributes.DEFAULT) // then .handle((result, ex) -> { assertInstanceOf(OperationException.class, ex); @@ -126,7 +126,7 @@ void lopGetSingle() throws Exception { // given String key = keys.get(0); - async.lopInsert(key, 0, VALUES.get(0), new CollectionAttributes()) + async.lopInsert(key, 0, VALUES.get(0), CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -155,7 +155,7 @@ void lopGetSingleNotFoundElement() throws Exception { // given String key = keys.get(0); - async.lopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.lopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -173,7 +173,7 @@ void lopGetSingleWithDelete() throws Exception { // given String key = keys.get(0); - async.lopInsert(key, 0, VALUES.get(0), new CollectionAttributes()) + async.lopInsert(key, 0, VALUES.get(0), CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -195,7 +195,7 @@ void lopGetRange() throws Exception { // given String key = keys.get(0); - async.lopInsert(key, 0, VALUES.get(0), new CollectionAttributes()) + async.lopInsert(key, 0, VALUES.get(0), CreateAttributes.DEFAULT) .thenCompose(result -> async.lopInsert(key, 1, VALUES.get(1))) .thenCompose(result -> async.lopInsert(key, 2, VALUES.get(2))) .toCompletableFuture() @@ -228,7 +228,7 @@ void lopGetRangeNotFoundElement() throws Exception { // given String key = keys.get(0); - async.lopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.lopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -246,7 +246,7 @@ void lopGetRangeWithDeleteAndDropIfEmpty() throws Exception { // given String key = keys.get(0); - async.lopInsert(key, 0, VALUES.get(0), new CollectionAttributes()) + async.lopInsert(key, 0, VALUES.get(0), CreateAttributes.DEFAULT) .thenCompose(result -> async.lopInsert(key, 1, VALUES.get(1))) .thenCompose(result -> async.lopInsert(key, 2, VALUES.get(2))) .toCompletableFuture() @@ -269,7 +269,7 @@ void lopDeleteSuccess() throws Exception { // given String key = keys.get(0); - async.lopInsert(key, 0, VALUES.get(0), new CollectionAttributes()) + async.lopInsert(key, 0, VALUES.get(0), CreateAttributes.DEFAULT) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -290,7 +290,7 @@ void lopDeleteRangeSuccess() throws Exception { // given String key = keys.get(0); - async.lopInsert(key, 0, VALUES.get(0), new CollectionAttributes()) + async.lopInsert(key, 0, VALUES.get(0), CreateAttributes.DEFAULT) .thenCompose(result -> async.lopInsert(key, 1, VALUES.get(1))) .thenCompose(result -> async.lopInsert(key, 2, VALUES.get(2))) .toCompletableFuture() @@ -313,7 +313,7 @@ void lopDeleteNotFoundElement() throws Exception { // given String key = keys.get(0); - async.lopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.lopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); diff --git a/src/test/java/net/spy/memcached/v2/MapAsyncArcusCommandsTest.java b/src/test/java/net/spy/memcached/v2/MapAsyncArcusCommandsTest.java index 8686401cd..ab208ed7f 100644 --- a/src/test/java/net/spy/memcached/v2/MapAsyncArcusCommandsTest.java +++ b/src/test/java/net/spy/memcached/v2/MapAsyncArcusCommandsTest.java @@ -6,7 +6,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import net.spy.memcached.collection.CollectionAttributes; +import net.spy.memcached.collection.CreateAttributes; import net.spy.memcached.collection.ElementValueType; import net.spy.memcached.ops.OperationException; import net.spy.memcached.v2.vo.GetMode; @@ -35,7 +35,7 @@ void mopCreate() throws ExecutionException, InterruptedException, TimeoutExcepti String key = keys.get(0); // when - async.mopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.mopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) // then .thenAccept(Assertions::assertTrue) .toCompletableFuture() @@ -47,13 +47,13 @@ void mopCreateAlreadyExists() throws ExecutionException, InterruptedException, T // given String key = keys.get(0); - async.mopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.mopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); // when - async.mopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.mopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) // then .thenAccept(Assertions::assertFalse) .toCompletableFuture() @@ -65,7 +65,7 @@ void mopInsert() throws ExecutionException, InterruptedException, TimeoutExcepti // given String key = keys.get(0); - async.mopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.mopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -95,7 +95,7 @@ void mopInsertWithAttributes() throws ExecutionException, InterruptedException, String key = keys.get(0); // when - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) // then .thenCompose(result -> { assertTrue(result); @@ -111,7 +111,7 @@ void mopInsertDuplicate() throws ExecutionException, InterruptedException, Timeo // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -135,7 +135,7 @@ void mopInsertTypeMismatch() throws ExecutionException, InterruptedException, Ti .get(300L, TimeUnit.MILLISECONDS); // when - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) // then .handle((result, ex) -> { assertInstanceOf(OperationException.class, ex); @@ -151,7 +151,7 @@ void mopUpsertInsert() throws ExecutionException, InterruptedException, TimeoutE // given String key = keys.get(0); - async.mopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.mopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -173,7 +173,7 @@ void mopUpsertReplace() throws ExecutionException, InterruptedException, Timeout // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -205,7 +205,7 @@ void mopUpdate() throws ExecutionException, InterruptedException, TimeoutExcepti // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -228,7 +228,7 @@ void mopUpdateNotFoundElement() throws ExecutionException, InterruptedException, // given String key = keys.get(0); - async.mopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.mopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -257,7 +257,7 @@ void mopGetAll() throws ExecutionException, InterruptedException, TimeoutExcepti // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenCompose(result -> async.mopInsert(key, MKEY2, VALUE2)) .thenCompose(result -> async.mopInsert(key, MKEY3, VALUE3)) .toCompletableFuture() @@ -294,7 +294,7 @@ void mopGetAllNotFoundElement() throws ExecutionException, InterruptedException, // given String key = keys.get(0); - async.mopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.mopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -315,7 +315,7 @@ void mopGetSingle() throws ExecutionException, InterruptedException, TimeoutExce // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -345,7 +345,7 @@ void mopGetSingleNotFoundElement() throws ExecutionException, InterruptedExcepti // given String key = keys.get(0); - async.mopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.mopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -364,7 +364,7 @@ void mopGetMultipleKeys() throws ExecutionException, InterruptedException, Timeo String key = keys.get(0); List mKeys = Arrays.asList(MKEY1, MKEY2); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenCompose(result -> async.mopInsert(key, MKEY2, VALUE2)) .thenCompose(result -> async.mopInsert(key, MKEY3, VALUE3)) .toCompletableFuture() @@ -389,7 +389,7 @@ void mopGetMultipleKeysNotFoundElement() throws ExecutionException, InterruptedE // given String key = keys.get(0); - async.mopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.mopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -411,7 +411,7 @@ void mopGetMultipleKeysPartialFound() throws ExecutionException, InterruptedExce // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenCompose(result -> async.mopInsert(key, MKEY2, VALUE2)) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -434,7 +434,7 @@ void mopGetAllWithDelete() throws ExecutionException, InterruptedException, Time // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -457,7 +457,7 @@ void mopDelete() throws ExecutionException, InterruptedException, TimeoutExcepti // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenCompose(result -> async.mopInsert(key, MKEY2, VALUE2)) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -482,7 +482,7 @@ void mopDeleteDropIfEmpty() throws ExecutionException, InterruptedException, Tim // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -514,7 +514,7 @@ void mopDeleteSingle() throws ExecutionException, InterruptedException, TimeoutE // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenCompose(result -> async.mopInsert(key, MKEY2, VALUE2)) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -542,7 +542,7 @@ void mopDeleteSingleNotFoundElement() throws ExecutionException, InterruptedExce // given String key = keys.get(0); - async.mopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.mopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -571,7 +571,7 @@ void mopDeleteSingleDropIfEmpty() throws ExecutionException, InterruptedExceptio // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -593,7 +593,7 @@ void mopDeleteMultiple() throws ExecutionException, InterruptedException, Timeou // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.mopInsert(key, MKEY2, VALUE2); @@ -630,7 +630,7 @@ void mopDeleteMultipleNotFoundElement() throws ExecutionException, InterruptedEx // given String key = keys.get(0); - async.mopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.mopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -649,7 +649,7 @@ void mopDeleteMultipleDropIfEmpty() throws ExecutionException, InterruptedExcept // given String key = keys.get(0); - async.mopInsert(key, MKEY1, VALUE1, new CollectionAttributes()) + async.mopInsert(key, MKEY1, VALUE1, CreateAttributes.DEFAULT) .thenCompose(result -> { assertTrue(result); return async.mopInsert(key, MKEY2, VALUE2); diff --git a/src/test/java/net/spy/memcached/v2/SetAsyncArcusCommandsTest.java b/src/test/java/net/spy/memcached/v2/SetAsyncArcusCommandsTest.java index 40d29a48b..41df42ccc 100644 --- a/src/test/java/net/spy/memcached/v2/SetAsyncArcusCommandsTest.java +++ b/src/test/java/net/spy/memcached/v2/SetAsyncArcusCommandsTest.java @@ -2,7 +2,7 @@ import java.util.concurrent.TimeUnit; -import net.spy.memcached.collection.CollectionAttributes; +import net.spy.memcached.collection.CreateAttributes; import net.spy.memcached.collection.ElementValueType; import net.spy.memcached.ops.OperationException; import net.spy.memcached.v2.vo.GetMode; @@ -23,7 +23,7 @@ void sopCreate() throws Exception { String key = keys.get(0); // when - async.sopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.sopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) // then .thenAccept(Assertions::assertTrue) .toCompletableFuture() @@ -35,13 +35,13 @@ void sopCreateAlreadyExists() throws Exception { // given String key = keys.get(0); - async.sopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.sopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); // when - async.sopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.sopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) // then .thenAccept(Assertions::assertFalse) .toCompletableFuture() @@ -53,7 +53,7 @@ void sopInsert() throws Exception { // given String key = keys.get(0); - async.sopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.sopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -82,7 +82,7 @@ void sopInsertWithAttributes() throws Exception { String key = keys.get(0); // when - async.sopInsert(key, VALUE, new CollectionAttributes()) + async.sopInsert(key, VALUE, CreateAttributes.DEFAULT) // then .thenCompose(result -> { assertTrue(result); @@ -98,7 +98,7 @@ void sopInsertDuplicate() throws Exception { // given String key = keys.get(0); - async.sopInsert(key, VALUE, new CollectionAttributes()) + async.sopInsert(key, VALUE, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -122,7 +122,7 @@ void sopInsertTypeMismatch() throws Exception { .get(300L, TimeUnit.MILLISECONDS); // when - async.sopInsert(key, VALUE, new CollectionAttributes()) + async.sopInsert(key, VALUE, CreateAttributes.DEFAULT) // then .handle((result, ex) -> { assertInstanceOf(OperationException.class, ex); @@ -138,7 +138,7 @@ void sopExistTrue() throws Exception { // given String key = keys.get(0); - async.sopInsert(key, VALUE, new CollectionAttributes()) + async.sopInsert(key, VALUE, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -156,7 +156,7 @@ void sopExistFalse() throws Exception { // given String key = keys.get(0); - async.sopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.sopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -207,7 +207,7 @@ void sopGet() throws Exception { // given String key = keys.get(0); - async.sopInsert(key, "v0", new CollectionAttributes()) + async.sopInsert(key, "v0", CreateAttributes.DEFAULT) .thenCompose(result -> async.sopInsert(key, "v1")) .thenCompose(result -> async.sopInsert(key, "v2")) .toCompletableFuture() @@ -240,7 +240,7 @@ void sopGetNotFoundElement() throws Exception { // given String key = keys.get(0); - async.sopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.sopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -258,7 +258,7 @@ void sopGetWithDelete() throws Exception { // given String key = keys.get(0); - async.sopInsert(key, VALUE, new CollectionAttributes()) + async.sopInsert(key, VALUE, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -280,7 +280,7 @@ void sopDelete() throws Exception { // given String key = keys.get(0); - async.sopInsert(key, VALUE, new CollectionAttributes()) + async.sopInsert(key, VALUE, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -312,7 +312,7 @@ void sopDeleteNotFoundElement() throws Exception { // given String key = keys.get(0); - async.sopCreate(key, ElementValueType.STRING, new CollectionAttributes()) + async.sopCreate(key, ElementValueType.STRING, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); @@ -330,7 +330,7 @@ void sopDeleteDropIfEmpty() throws Exception { // given String key = keys.get(0); - async.sopInsert(key, VALUE, new CollectionAttributes()) + async.sopInsert(key, VALUE, CreateAttributes.DEFAULT) .thenAccept(Assertions::assertTrue) .toCompletableFuture() .get(300L, TimeUnit.MILLISECONDS); diff --git a/src/test/java/net/spy/memcached/v2/attribute/ItemAttributesTest.java b/src/test/java/net/spy/memcached/v2/attribute/ItemAttributesTest.java new file mode 100644 index 000000000..a574e1c50 --- /dev/null +++ b/src/test/java/net/spy/memcached/v2/attribute/ItemAttributesTest.java @@ -0,0 +1,47 @@ +package net.spy.memcached.v2.attribute; + +import net.spy.memcached.collection.CollectionOverflowAction; +import net.spy.memcached.collection.CollectionType; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class ItemAttributesTest { + + @Test + void parsesCommandAttributes() { + ItemAttributes r = new ItemAttributes(); + r.setAttribute("flags=0"); + r.setAttribute("expiretime=2208988800"); // > Integer.MAX_VALUE + r.setAttribute("type=list"); + r.setAttribute("count=3"); + r.setAttribute("maxcount=4000"); + r.setAttribute("overflowaction=error"); + r.setAttribute("readable=on"); + + assertEquals(Integer.valueOf(0), r.getFlags()); + assertEquals(Long.valueOf(2208988800L), r.getExpireTime()); + assertEquals(CollectionType.list, r.getType()); + assertEquals(Long.valueOf(3L), r.getCount()); + assertEquals(Long.valueOf(4000L), r.getMaxCount()); + assertEquals(CollectionOverflowAction.error, r.getOverflowAction()); + assertEquals(Boolean.TRUE, r.getReadable()); + } + + @Test + void unsetFieldsAreNull() { + ItemAttributes r = new ItemAttributes(); + assertNull(r.getMaxBKeyRange()); + assertNull(r.getMinBKey()); + assertNull(r.getTrimmed()); + } + + @Test + void parsesLongBKeyRange() { + ItemAttributes r = new ItemAttributes(); + r.setAttribute("maxbkeyrange=100"); + assertEquals(100L, (long) r.getMaxBKeyRange().getData()); + } +} diff --git a/src/test/java/net/spy/memcached/v2/attribute/UpdateAttributesTest.java b/src/test/java/net/spy/memcached/v2/attribute/UpdateAttributesTest.java new file mode 100644 index 000000000..1613df212 --- /dev/null +++ b/src/test/java/net/spy/memcached/v2/attribute/UpdateAttributesTest.java @@ -0,0 +1,55 @@ +package net.spy.memcached.v2.attribute; + +import net.spy.memcached.collection.CollectionOverflowAction; +import net.spy.memcached.v2.vo.BKey; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class UpdateAttributesTest { + + @Test + void emptyProducesEmptyClause() { + assertThrows(IllegalArgumentException.class, () -> UpdateAttributes.builder().build()); + } + + @Test + void maxBKeyRangeAppears() { + UpdateAttributes attr = UpdateAttributes.builder() + .maxBKeyRange(BKey.of(100L)) + .build(); + + assertEquals("maxbkeyrange=100", attr.stringify()); + } + + @Test + void onlySetFieldsAppear() { + UpdateAttributes attr = UpdateAttributes.builder() + .expireTime(3_000_000_000L) // out of int range + .build(); + + assertEquals("expiretime=3000000000", attr.stringify()); + } + + @Test + void multipleFieldsJoinedBySpace() { + UpdateAttributes attr = UpdateAttributes.builder() + .maxCount(2_000L) + .overflowAction(CollectionOverflowAction.error) + .readable(true) + .build(); + + assertEquals("maxcount=2000 overflowaction=error readable=on", attr.stringify()); + } + + @Test + void getLengthMatchesStringify() { + UpdateAttributes attr = UpdateAttributes.builder() + .expireTime(60L) + .build(); + + assertEquals(attr.stringify().length(), attr.getLength()); + } +} diff --git a/src/test/manual/net/spy/memcached/MultibyteKeyTest.java b/src/test/manual/net/spy/memcached/MultibyteKeyTest.java index 056999d26..6134c7957 100644 --- a/src/test/manual/net/spy/memcached/MultibyteKeyTest.java +++ b/src/test/manual/net/spy/memcached/MultibyteKeyTest.java @@ -46,6 +46,7 @@ import net.spy.memcached.collection.CollectionOverflowAction; import net.spy.memcached.collection.CollectionPipedInsert; import net.spy.memcached.collection.CollectionPipedUpdate; +import net.spy.memcached.collection.CreateAttributes; import net.spy.memcached.collection.Element; import net.spy.memcached.collection.ElementFlagFilter; import net.spy.memcached.collection.ElementFlagUpdate; @@ -328,9 +329,10 @@ public void complete() { for (int i = 0; i < 10; i++) { elements.add(new Element<>(Long.valueOf(i), new Random().nextInt(), new byte[]{1, 1})); } + CollectionAttributes attr = new CollectionAttributes(); CollectionPipedInsert insert = new CollectionPipedInsert.ByteArraysBTreePipedInsert<>( - MULTIBYTE_KEY, elements, new CollectionAttributes(), new IntegerTranscoder()); + MULTIBYTE_KEY, elements, CreateAttributes.of(attr), new IntegerTranscoder()); try { opFact.collectionPipedInsert(MULTIBYTE_KEY, insert, cpsCallback).initialize(); } catch (java.nio.BufferOverflowException e) { @@ -342,7 +344,7 @@ public void complete() { elementsMap.put(Long.valueOf(i), new Random().nextInt()); } insert = new CollectionPipedInsert.BTreePipedInsert<>( - MULTIBYTE_KEY, elementsMap, new CollectionAttributes(), new IntegerTranscoder()); + MULTIBYTE_KEY, elementsMap, CreateAttributes.of(attr), new IntegerTranscoder()); try { opFact.collectionPipedInsert(MULTIBYTE_KEY, insert, cpsCallback).initialize(); } catch (java.nio.BufferOverflowException e) { @@ -354,7 +356,7 @@ public void complete() { elementsList.add(new Random().nextInt()); } insert = new CollectionPipedInsert.ListPipedInsert<>( - MULTIBYTE_KEY, 0, elementsList, new CollectionAttributes(), + MULTIBYTE_KEY, 0, elementsList, CreateAttributes.of(attr), new IntegerTranscoder()); try { opFact.collectionPipedInsert(MULTIBYTE_KEY, insert, cpsCallback).initialize(); @@ -367,7 +369,7 @@ public void complete() { elementsSet.add(new Random().nextInt()); } insert = new CollectionPipedInsert.SetPipedInsert<>( - MULTIBYTE_KEY, elementsSet, new CollectionAttributes(), new IntegerTranscoder()); + MULTIBYTE_KEY, elementsSet, CreateAttributes.of(attr), new IntegerTranscoder()); try { opFact.collectionPipedInsert(MULTIBYTE_KEY, insert, cpsCallback).initialize(); } catch (java.nio.BufferOverflowException e) { @@ -446,10 +448,13 @@ public void complete() { } }; + CollectionAttributes attr = new CollectionAttributes(); insert = new CollectionBulkInsert.BTreeBulkInsert<>(null, keyList, - String.valueOf(1L), BTreeUtil.toHex(new byte[]{0, 0}), - new IntegerTranscoder().encode(new Random().nextInt()), - new CollectionAttributes()); + String.valueOf(1L), BTreeUtil.toHex(new byte[]{0, 0}), + new IntegerTranscoder().encode(new Random().nextInt()), + CreateAttributes.of(attr) + ); + try { opFact.collectionBulkInsert(insert, cbsCallback).initialize(); } catch (java.nio.BufferOverflowException e) { @@ -458,7 +463,7 @@ public void complete() { insert = new CollectionBulkInsert.ListBulkInsert<>(null, keyList, 0, new IntegerTranscoder().encode(new Random().nextInt()), - new CollectionAttributes()); + CreateAttributes.of(attr)); try { opFact.collectionBulkInsert(insert, cbsCallback).initialize(); @@ -468,7 +473,7 @@ public void complete() { insert = new CollectionBulkInsert.SetBulkInsert<>(null, keyList, new IntegerTranscoder().encode(new Random().nextInt()), - new CollectionAttributes()); + CreateAttributes.of(attr)); try { opFact.collectionBulkInsert(insert, cbsCallback).initialize(); } catch (java.nio.BufferOverflowException e) { @@ -573,9 +578,15 @@ public void complete() { @Test void CollectionCreateOperationImplTest() { try { - opFact.collectionCreate(MULTIBYTE_KEY, - new BTreeCreate(0, 0, 10000L, CollectionOverflowAction.error, true, false), - genericCallback).initialize(); + CreateAttributes attributes = CreateAttributes.builder() + .expireTime(0L) + .maxCount(10_000L) + .overflowAction(CollectionOverflowAction.error) + .readable(true) + .build(); + + BTreeCreate create = new BTreeCreate(0, attributes, false); + opFact.collectionCreate(MULTIBYTE_KEY, create, genericCallback).initialize(); } catch (java.nio.BufferOverflowException e) { fail(); } @@ -624,7 +635,7 @@ void BTreeInsertAndGetOperationImplTest() { try { opFact.bopInsertAndGet(MULTIBYTE_KEY, new BTreeInsertAndGet<>(1L, new byte[]{0, 0}, new Random().nextInt(), - false, new CollectionAttributes()), + false, CreateAttributes.of(new CollectionAttributes())), testData, new BTreeInsertAndGetOperation.Callback() { @Override public void gotData(int flags, BKeyObject bkeyObject, byte[] elementFlag, byte[] data) {