From 5b4864ba421580084247afc26addfe584bb6c2aa Mon Sep 17 00:00:00 2001 From: MinWooJin Date: Tue, 27 Sep 2016 11:05:22 +0900 Subject: [PATCH] MAP_COLLECTION: refactor map collection, remove MapElement... --- docs/07-map-API.md | 12 +- install-arcus-memcached.sh | 28 ----- .../java/net/spy/memcached/ArcusClient.java | 59 ++-------- .../java/net/spy/memcached/ArcusClientIF.java | 111 +++++------------- .../net/spy/memcached/ArcusClientPool.java | 25 +--- .../collection/CollectionCreate.java | 2 - .../collection/CollectionPipedStore.java | 93 +-------------- .../collection/CollectionPipedUpdate.java | 48 ++++---- .../collection/CollectionUpdate.java | 10 -- .../spy/memcached/collection/MapDelete.java | 2 +- .../spy/memcached/collection/MapElement.java | 71 ----------- .../spy/memcached/collection/MapUpdate.java | 2 +- .../net/spy/memcached/ArcusTimeoutTest.java | 14 +-- .../MopInsertBulkMultipleTest.java | 84 ++----------- .../bulkoperation/PipeInsertTest.java | 8 -- .../collection/map/MopBulkAPITest.java | 13 +- 16 files changed, 100 insertions(+), 482 deletions(-) delete mode 100644 install-arcus-memcached.sh delete mode 100644 src/main/java/net/spy/memcached/collection/MapElement.java diff --git a/docs/07-map-API.md b/docs/07-map-API.md index f77063e8..e8beaf23 100644 --- a/docs/07-map-API.md +++ b/docs/07-map-API.md @@ -6,7 +6,7 @@ Map을 Java의 Map 자료형을 저장하는 용도로 사용하길 권장한다 **제약 조건** - 저장 가능한 최대 element 개수 : 디폴트 4,000개 (attribute 설정으로 최대 50,000개 확장 가능) - 각 element에서 value 최대 크기 : 4KB -- mkey의 입력, Java map type에서 key는 string type만 가능하다. mkey 최대 길이는 key의 최대 길이와 같고, 하나의 map 내에서 mkey간의 중복은 허용하지 않는다. +- mkey의 입력, Java map type에서 key는 string type만 가능하다. mkey 최대 길이는 250 바이트 이고, 하나의 map에 중복된 mkey는 허용하지 않는다. Map item에 대해 수행가능한 기본 연산은 다음과 같다. @@ -269,14 +269,14 @@ Map element를 조회하는 함수는 세 유형이 있다. ```java CollectionFuture> -asyncMopGet(String key, boolean withDelete, Boolean dropIfEmpty) +asyncMopGet(String key, boolean withDelete, boolean dropIfEmpty) ``` 둘째, 해당 Map에서 주어진 mkey 하나의 element를 조회한다. ```java CollectionFuture> -asyncMopGet(String key, String mkey, boolean withDelete, Boolean dropIfEmpty) +asyncMopGet(String key, String mkey, boolean withDelete, boolean dropIfEmpty) ``` 셋째, Map에서 주어진 mkeyList의 element를 조회한다. @@ -364,8 +364,6 @@ Map에 여러 element를 한번에 삽입하는 함수는 두 유형이 있다. ```java CollectionFuture> asyncMopPipedInsertBulk(String key, Map elements, CollectionAttributes attributesForCreate) -CollectionFuture> -asyncMopPipedInsertBulk(String key, List elements, CollectionAttributes attributesForCreate) ``` - key: 삽입 대상 map의 key @@ -463,7 +461,7 @@ Map에서 주어진 elements에 해당하는 모든 element의 value를 일괄 ```java CollectionFuture> -asyncMopPipedUpdateBulk(String key, List> mapElements) +asyncMopPipedUpdateBulk(String key, Map> elements) ``` - key: 변경 대상 map의 key -- mapElements: 변경 대상 map에 대해 mkey, new value를 가진다. +- elements: 변경 대상 map에 대해 mkey, new value를 가진다. diff --git a/install-arcus-memcached.sh b/install-arcus-memcached.sh deleted file mode 100644 index ddc54015..00000000 --- a/install-arcus-memcached.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh -set -e -CWD=$(pwd) - -# check to see if arcus-memcached folder is empty -if [ ! -x "$HOME/arcus/bin/memcached" ] || [ ! -x "$HOME/arcus/zookeeper/bin/zkServer.sh" ] -then - echo "No arcus installation! running clone and build..." - git clone --recursive git://github.com/naver/arcus.git $HOME/arcus - cd $HOME/arcus/scripts && ./build.sh -else - echo "Using cached arcus installation" -fi - -# checkout develop in arcus-memcached -cd $HOME/arcus/server -git checkout develop -./config/autorun.sh -./configure --prefix=$HOME/arcus --enable-zk-integration --with-libevent=$HOME/arcus --with-zookeeper=$HOME/arcus -make -make install - -rm -rf $HOME/arcus/zookeeper/data -cp $CWD/mvnTestConf.json $HOME/arcus/scripts/conf/ -cd $HOME/arcus/scripts && - ./arcus.sh quicksetup conf/mvnTestConf.json - -cd $CWD diff --git a/src/main/java/net/spy/memcached/ArcusClient.java b/src/main/java/net/spy/memcached/ArcusClient.java index ba8ca26d..5c4e8920 100644 --- a/src/main/java/net/spy/memcached/ArcusClient.java +++ b/src/main/java/net/spy/memcached/ArcusClient.java @@ -108,7 +108,6 @@ import net.spy.memcached.collection.MapGet; import net.spy.memcached.collection.MapStore; import net.spy.memcached.collection.MapUpdate; -import net.spy.memcached.collection.MapElement; import net.spy.memcached.collection.SetCreate; import net.spy.memcached.collection.SetDelete; import net.spy.memcached.collection.SetExist; @@ -3039,25 +3038,25 @@ public CollectionFuture> asyncBopPip * (non-Javadoc) * * @see net.spy.memcached.ArcusClientIF#asyncMopUpdate(java.lang.String, - * net.spy.memcached.collection.MapElement, net.spy.memcached.transcoders.Transcoder) + * java.util.Map, net.spy.memcached.transcoders.Transcoder) */ @Override public CollectionFuture> asyncMopPipedUpdateBulk( - String key, List> mapElements) { - return asyncMopPipedUpdateBulk(key, mapElements, collectionTranscoder); + String key, Map elements) { + return asyncMopPipedUpdateBulk(key, elements, collectionTranscoder); } @Override public CollectionFuture> asyncMopPipedUpdateBulk( - String key, List> mapElements, Transcoder tc) { + String key, Map elements, Transcoder tc) { - if (mapElements.size() <= CollectionPipedUpdate.MAX_PIPED_ITEM_COUNT) { + if (elements.size() <= CollectionPipedUpdate.MAX_PIPED_ITEM_COUNT) { CollectionPipedUpdate collectionPipedUpdate = new MapPipedUpdate( - key, mapElements, tc); + key, elements, tc); return asyncCollectionPipedUpdate(key, collectionPipedUpdate); } else { - PartitionedList> list = new PartitionedList>( - mapElements, CollectionPipedUpdate.MAX_PIPED_ITEM_COUNT); + PartitionedMap list = new PartitionedMap( + elements, CollectionPipedUpdate.MAX_PIPED_ITEM_COUNT); List> collectionPipedUpdateList = new ArrayList>( list.size()); @@ -3928,48 +3927,6 @@ public void gotStatus(Integer index, OperationStatus status) { return rv; } - /* - * (non-Javadoc) - * @see net.spy.memcached.ArcusClientIF#asyncMopPipedInsertBulk(java.lang.String, java.util.List, boolean, net.spy.memcached.collection.CollectionAttributes) - */ - @Override - public CollectionFuture> asyncMopPipedInsertBulk( - String key, List> mapElements, - CollectionAttributes attributesForCreate) { - return asyncMopPipedInsertBulk(key, mapElements, attributesForCreate, - collectionTranscoder); - } - - /* - * (non-Javadoc) - * @see net.spy.memcached.ArcusClientIF#asyncMopPipedInsertBulk(java.lang.String, java.util.List, boolean, net.spy.memcached.collection.CollectionAttributes, net.spy.memcached.transcoders.Transcoder) - */ - @Override - public CollectionFuture> asyncMopPipedInsertBulk( - String key, List> mapElements, - CollectionAttributes attributesForCreate, Transcoder tc) { - if (mapElements.size() <= CollectionPipedStore.MAX_PIPED_ITEM_COUNT) { - CollectionPipedStore store = new CollectionPipedStore.MapElementsPipedStore( - key, mapElements, (attributesForCreate != null), - attributesForCreate, tc); - return asyncCollectionPipedStore(key, store); - } else { - PartitionedList> list = new PartitionedList>( - mapElements, CollectionPipedStore.MAX_PIPED_ITEM_COUNT); - - List> storeList = new ArrayList>( - list.size()); - - for (int i = 0; i < list.size(); i++) { - storeList.add(new CollectionPipedStore.MapElementsPipedStore(key, - list.get(i), (attributesForCreate != null), - attributesForCreate, tc)); - } - - return asyncCollectionPipedStore(key, storeList); - } - } - /* * (non-Javadoc) * @see net.spy.memcached.ArcusClientIF#asyncBopPipedInsertBulk(java.lang.String, java.util.List, boolean, net.spy.memcached.collection.CollectionAttributes) diff --git a/src/main/java/net/spy/memcached/ArcusClientIF.java b/src/main/java/net/spy/memcached/ArcusClientIF.java index 2bc6805d..d2653eeb 100644 --- a/src/main/java/net/spy/memcached/ArcusClientIF.java +++ b/src/main/java/net/spy/memcached/ArcusClientIF.java @@ -33,7 +33,6 @@ import net.spy.memcached.collection.ElementValueType; import net.spy.memcached.collection.SMGetElement; import net.spy.memcached.collection.SMGetMode; -import net.spy.memcached.collection.MapElement; import net.spy.memcached.internal.BTreeStoreAndGetFuture; import net.spy.memcached.internal.CollectionFuture; import net.spy.memcached.internal.CollectionGetBulkFuture; @@ -49,9 +48,9 @@ public interface ArcusClientIF { /** * Sets attributes (metadata) associated with each key - * of collections including lists, sets, and B+ trees. + * of collections including lists, sets, maps, and B+ trees. * - * @param key key of a collection (list, set, B+ tree) + * @param key key of a collection (list, set, map, B+ tree) * @param attrs a collectionAttribute object to set * @return whether or not the operation was performed */ @@ -60,9 +59,9 @@ public abstract CollectionFuture asyncSetAttr(String key, /** * Gets attributes (metadata) associated with each key - * of collections including lists, sets, and B+ trees. + * of collections including lists, sets, maps, and B+ trees. * - * @param key key of a collection (list, set, B+ tree) + * @param key key of a collection (list, set, map, B+ tree) * @return a CollectionAttributes object containing attributes */ public abstract CollectionFuture asyncGetAttr( @@ -209,9 +208,9 @@ public abstract Future> asyncBopInsertBul * @param mkey * mkey of map. * @param value - * value of map + * value of map * @param attributesForCreate - * create a b+tree with this attributes, if given key is not + * create a map with this attributes, if given key is not * exists. * @param tc * transcoder to encode value @@ -229,9 +228,9 @@ public abstract Future> asyncMopInser * @param mkey * mkey of map. * @param value - * value of map + * value of map * @param attributesForCreate - * create a b+tree with this attributes, if given key is not + * create a map with this attributes, if given key is not * exists. * @return a future indicating success */ @@ -505,53 +504,47 @@ public CollectionFuture>> asyncBopGet(String key, boolean withDelete, boolean dropIfEmpty, Transcoder tc); /** - * Retrieves count all items of random in the map + * Retrieves all items from the map * * @param key key of a map * @param withDelete true to remove the returned item in the map - * @param dropIfEmpty false to remove the key when all elements are removed. true map will remain empty even if all the elements are removed + * @param dropIfEmpty true to remove the key when all elements are removed. false map will remain empty even if all the elements are removed * @return a future that will hold the return value map of the fetch */ public CollectionFuture> asyncMopGet(String key, boolean withDelete, boolean dropIfEmpty); /** - * Retrieves count all items in given mkey - * The returned map from the future should be sorted by the given range. + * Retrieves an item on given mkey in the map. * * @param key key of a map * @param mkey mkey of a map * @param withDelete true to remove the returned item in the map - * @param dropIfEmpty false to remove the key when all elements are removed. true map will remain empty even if all the elements are removed + * @param dropIfEmpty true to remove the key when all elements are removed. false map will remain empty even if all the elements are removed * @return a future that will hold the return value map of the fetch */ public CollectionFuture> asyncMopGet(String key, String mkey, boolean withDelete, boolean dropIfEmpty); /** - * Retrieves an item on given mkeyList in the map. + * Retrieves items on given mkey list in the map. * - * @param key - * key of a map - * @param mkeyList - * mkeyList - * @param withDelete - * true to remove the returned item in the b+tree - * @param dropIfEmpty - * false to remove the key when all elements are removed. true b+ - * tree will remain empty even if all the elements are removed + * @param key key of a map + * @param mkeyList mkeyList + * @param withDelete true to remove the returned item in the map + * @param dropIfEmpty true to remove the key when all elements are removed. false map will remain empty even if all the elements are removed * @return a future that will hold the return value map of the fetch. */ public CollectionFuture> asyncMopGet(String key, List mkeyList, boolean withDelete, boolean dropIfEmpty); /** - * Retrieves count all items of random in the map + * Retrieves all items from the map * * @param * @param key key of a map - * @param withDelete true to remove the returned item in the b+tree - * @param dropIfEmpty false to remove the key when all elements are removed. true b+ tree will remain empty even if all the elements are removed + * @param withDelete true to remove the returned item in the map + * @param dropIfEmpty true to remove the key when all elements are removed. false map will remain empty even if all the elements are removed * @param tc a transcoder to decode returned values * @return a future that will hold the return value map of the fetch */ @@ -559,14 +552,13 @@ public CollectionFuture> asyncMopGet(String key, boolean withDelete, boolean dropIfEmpty, Transcoder tc); /** - * Retrieves count of all items in given mkey - * The returned map from the future should be sorted by the given range. + * Retrieves an item on given mkey in the map. * * @param * @param key key of a map * @param mkey mkey of a map - * @param withDelete true to remove the returned item in the b+tree - * @param dropIfEmpty false to remove the key when all elements are removed. true b+ tree will remain empty even if all the elements are removed + * @param withDelete true to remove the returned item in the map + * @param dropIfEmpty true to remove the key when all elements are removed. false map will remain empty even if all the elements are removed * @param tc a transcoder to decode returned values * @return a future that will hold the return value map of the fetch */ @@ -574,13 +566,13 @@ public CollectionFuture> asyncMopGet(String key, String mkey, boolean withDelete, boolean dropIfEmpty, Transcoder tc); /** - * Retrieves an item on given mkeyList in the map + * Retrieves items on given mkey list in the map. * * @param * @param key key of a map * @param mkeyList mkeyList - * @param withDelete true to remove the returned item in the b+tree - * @param dropIfEmpty false to remove the key when all elements are removed. true b+ tree will remain empty even if all the elements are removed + * @param withDelete true to remove the returned item in the map + * @param dropIfEmpty true to remove the key when all elements are removed. false map will remain empty even if all the elements are removed * @param tc a transcoder to decode returned values * @return a future that will hold the return value map of the fetch. */ @@ -1205,7 +1197,6 @@ public CollectionFuture asyncBopUpdate(String key, long bkey, * key of a map element * @param value * new value of element. - * do not update the value if this argument is null. * @return a future indicating success */ public CollectionFuture asyncMopUpdate (String key, String mkey, @@ -1220,7 +1211,6 @@ public CollectionFuture asyncMopUpdate (String key, String mkey, * key of a map element * @param value * new value of element. - * do not update the value if this argument is null. * @param tc * a transcoder to encode the value of element * @return a future indicating success @@ -1259,26 +1249,26 @@ public CollectionFuture> asyncBopPip * * @param key * key of a map - * @param mapElements - * list of map element + * @param elements + * Map of map element * @return a future indicating success */ public CollectionFuture> asyncMopPipedUpdateBulk( - String key, List> mapElements); + String key, Map elements); /** * Update elements from the map * * @param key * key of a map - * @param mapElements - * list of map element + * @param elements + * Map of map element * @param tc * a transcoder to encode the value of element * @return a future indicating success */ public CollectionFuture> asyncMopPipedUpdateBulk( - String key, List> mapElements, Transcoder tc); + String key, Map elements, Transcoder tc); /** * Insert an item into the b+tree @@ -1509,43 +1499,6 @@ public CollectionFuture> asyncSopPipedExistBulk( public CollectionFuture> asyncSopPipedExistBulk( String key, List values, Transcoder tc); - /** - * Insert elements into a map - * - * @param key - * a key list of map - * @param mapElements - * mapElement list which insert into map - * @param attributesForCreate - * create a b+tree with this attributes, if given key is not - * exists. - * @return a future that will hold the index of iteration sequence which - * failed elements and result code. - * - */ - public CollectionFuture> asyncMopPipedInsertBulk( - String key, List> mapElements, - CollectionAttributes attributesForCreate); - - /** - * Insert elements into a map - * - * @param key - * a key list of map - * @param mapElements - * MapElement list which insert into map - * @param attributesForCreate - * create a b+tree with this attributes, if given key is not exists. - * @param tc - * transcoder to decode value - * @return a future that will hold the index of iteration sequence which - * failed elements and result code. - * - */ - public CollectionFuture> asyncMopPipedInsertBulk( - String key, List> mapElements, - CollectionAttributes attributesForCreate, Transcoder tc); - /** * Insert elements into a b+tree * diff --git a/src/main/java/net/spy/memcached/ArcusClientPool.java b/src/main/java/net/spy/memcached/ArcusClientPool.java index 6f9a202f..bc5ff558 100644 --- a/src/main/java/net/spy/memcached/ArcusClientPool.java +++ b/src/main/java/net/spy/memcached/ArcusClientPool.java @@ -39,7 +39,6 @@ import net.spy.memcached.collection.ElementValueType; import net.spy.memcached.collection.SMGetElement; import net.spy.memcached.collection.SMGetMode; -import net.spy.memcached.collection.MapElement; import net.spy.memcached.internal.BTreeStoreAndGetFuture; import net.spy.memcached.internal.BulkFuture; import net.spy.memcached.internal.CollectionFuture; @@ -905,14 +904,14 @@ public CollectionFuture> asyncBopPip @Override public CollectionFuture> asyncMopPipedUpdateBulk( - String key, List> mapElements) { - return this.getClient().asyncMopPipedUpdateBulk(key, mapElements); + String key, Map elements) { + return this.getClient().asyncMopPipedUpdateBulk(key, elements); } @Override public CollectionFuture> asyncMopPipedUpdateBulk( - String key, List> mapElements, Transcoder tc) { - return this.getClient().asyncMopPipedUpdateBulk(key, mapElements, tc); + String key, Map elements, Transcoder tc) { + return this.getClient().asyncMopPipedUpdateBulk(key, elements, tc); } @Override @@ -927,22 +926,6 @@ public CollectionFuture> asyncSopPipedExistBulk( return this.getClient().asyncSopPipedExistBulk(key, values, tc); } - @Override - public CollectionFuture> asyncMopPipedInsertBulk( - String key, List> mapElements, - CollectionAttributes attributesForCreate) { - return this.getClient().asyncMopPipedInsertBulk(key, mapElements, - attributesForCreate); - } - - @Override - public CollectionFuture> asyncMopPipedInsertBulk( - String key, List> mapElements, - CollectionAttributes attributesForCreate, Transcoder tc) { - return this.getClient().asyncMopPipedInsertBulk(key, mapElements, - attributesForCreate, tc); - } - @Override public CollectionFuture> asyncBopPipedInsertBulk( String key, List> elements, diff --git a/src/main/java/net/spy/memcached/collection/CollectionCreate.java b/src/main/java/net/spy/memcached/collection/CollectionCreate.java index 6dae78dc..186a39e7 100644 --- a/src/main/java/net/spy/memcached/collection/CollectionCreate.java +++ b/src/main/java/net/spy/memcached/collection/CollectionCreate.java @@ -16,8 +16,6 @@ */ package net.spy.memcached.collection; -import java.util.IllegalFormatCodePointException; - public abstract class CollectionCreate { protected int flags; protected int expTime; diff --git a/src/main/java/net/spy/memcached/collection/CollectionPipedStore.java b/src/main/java/net/spy/memcached/collection/CollectionPipedStore.java index e36b5d38..8fd82c9d 100644 --- a/src/main/java/net/spy/memcached/collection/CollectionPipedStore.java +++ b/src/main/java/net/spy/memcached/collection/CollectionPipedStore.java @@ -396,7 +396,7 @@ public MapPipedStore(String key, Map map, public ByteBuffer getAsciiCommand() { int capacity = 0; - // decode values + // encode values List encodedList = new ArrayList(map.size()); CachedData cd = null; for (T each : map.values()) { @@ -417,9 +417,9 @@ public ByteBuffer getAsciiCommand() { ByteBuffer bb = ByteBuffer.allocate(capacity); // create ascii operation string - int keySize = map.keySet().size(); + int mkeySize = map.keySet().size(); List keyList = new ArrayList(map.keySet()); - for(i = this.nextOpIndex; i < keySize; i++) { + for(i = this.nextOpIndex; i < mkeySize; i++) { String mkey = keyList.get(i); byte[] value = encodedList.get(i); @@ -429,92 +429,7 @@ public ByteBuffer getAsciiCommand() { (createKeyIfNotExists) ? (attribute != null && attribute.getMaxCount() != null) ? attribute.getMaxCount() : CollectionAttributes.DEFAULT_MAXCOUNT : "", (createKeyIfNotExists) ? (attribute != null && attribute.getOverflowAction() != null) ? attribute.getOverflowAction() : "" : "", (createKeyIfNotExists) ? (attribute != null && attribute.getReadable() != null && !attribute.getReadable()) ? "unreadable" : "" : "", - (i < keySize - 1) ? PIPE : ""); - bb.put(value); - bb.put(CRLF); - } - - // flip the buffer - bb.flip(); - - return bb; - } - - public ByteBuffer getBinaryCommand() { - throw new RuntimeException("not supported in binary protocol yet."); - } - } - - /** - * - */ - public static class MapElementsPipedStore extends CollectionPipedStore { - - private static final String COMMAND = "mop insert"; - private List> mapElements; - - public MapElementsPipedStore(String key, List> mapElements, - boolean createKeyIfNotExists, CollectionAttributes attr, Transcoder tc) { - if (createKeyIfNotExists) { - CollectionOverflowAction overflowAction = attr.getOverflowAction(); - if (overflowAction != null && - !CollectionType.map.isAvailableOverflowAction(overflowAction)) - throw new IllegalArgumentException(overflowAction + " is unavailable overflow action in " + CollectionType.map + "."); - } - this.key = key; - this.mapElements = mapElements; - this.createKeyIfNotExists = createKeyIfNotExists; - this.attribute = attr; - this.tc = tc; - this.itemCount = mapElements.size(); - } - - public ByteBuffer getAsciiCommand() { - int capacity = 0; - - // decode values - List encodedList = new ArrayList(mapElements.size()); - CachedData cd = null; - for (MapElement each : mapElements) { - cd = tc.encode(each.getValue()); - encodedList.add(cd.getData()); - } - - // estimate the buffer capacity - int i = 0; - for (MapElement eachMkey : mapElements) { - capacity += KeyUtil.getKeyBytes(key).length; - capacity += KeyUtil.getKeyBytes(eachMkey.getMkey()).length; - capacity += encodedList.get(i++).length; - capacity += 64; - } - - // allocate the buffer - ByteBuffer bb = ByteBuffer.allocate(capacity); - - // create ascii operation string - int fSize = mapElements.size(); - for(i = this.nextOpIndex; i < fSize; i++) { - MapElement mapMkey = mapElements.get(i); - byte[] value = encodedList.get(i); - - setArguments(bb, COMMAND, key, mapMkey.getMkey(), value.length, - (createKeyIfNotExists) ? "create" : "", - (createKeyIfNotExists) ? cd.getFlags() : "", - (createKeyIfNotExists) ? (attribute != null && attribute. - getExpireTime() != null) ? attribute. - getExpireTime() : CollectionAttributes.DEFAULT_EXPIRETIME : "", - (createKeyIfNotExists) ? (attribute != null && attribute. - getMaxCount() != null) ? attribute. - getMaxCount() : CollectionAttributes.DEFAULT_MAXCOUNT : "", - (createKeyIfNotExists) ? (attribute != null && attribute - .getOverflowAction() != null) ? attribute - .getOverflowAction().toString() - : "" : "", - (createKeyIfNotExists) ? (attribute != null && attribute - .getReadable() != null && !attribute.getReadable()) ? - "unreadable" : "" : "", - (i < fSize - 1) ? PIPE : ""); + (i < mkeySize - 1) ? PIPE : ""); bb.put(value); bb.put(CRLF); } diff --git a/src/main/java/net/spy/memcached/collection/CollectionPipedUpdate.java b/src/main/java/net/spy/memcached/collection/CollectionPipedUpdate.java index e7494a00..8f3e5032 100644 --- a/src/main/java/net/spy/memcached/collection/CollectionPipedUpdate.java +++ b/src/main/java/net/spy/memcached/collection/CollectionPipedUpdate.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; import net.spy.memcached.CachedData; import net.spy.memcached.KeyUtil; @@ -34,6 +35,7 @@ public abstract class CollectionPipedUpdate extends CollectionObject { protected String key; protected Transcoder tc; protected int itemCount; + protected int nextOpIndex = 0; public abstract ByteBuffer getAsciiCommand(); @@ -145,29 +147,25 @@ public ByteBuffer getBinaryCommand() { public static class MapPipedUpdate extends CollectionPipedUpdate { private static final String COMMAND = "mop update"; - private List> mapElements; + private Map elements; - public MapPipedUpdate(String key, List> mapElements, + public MapPipedUpdate(String key, Map elements, Transcoder tc) { this.key = key; - this.mapElements = mapElements; + this.elements = elements; this.tc = tc; - this.itemCount = mapElements.size(); + this.itemCount = elements.size(); } public ByteBuffer getAsciiCommand() { int capacity = 0; - // decode parameters - List encodedList = new ArrayList(mapElements.size()); + // encode parameters + List encodedList = new ArrayList(elements.size()); CachedData cd = null; - for (MapElement each : mapElements) { - if (each.getValue() != null) { - cd = tc.encode(each.getValue()); - encodedList.add(cd.getData()); - } else { - encodedList.add(null); - } + for (T each : elements.values()) { + cd = tc.encode(each); + encodedList.add(cd.getData()); } // estimate the buffer capacity @@ -175,12 +173,10 @@ public ByteBuffer getAsciiCommand() { byte[] value; StringBuilder b; - for (MapElement each : mapElements) { + for (String eachMkey : elements.keySet()) { capacity += KeyUtil.getKeyBytes(key).length; - capacity += KeyUtil.getKeyBytes(each.getMkey()).length; - if (encodedList.get(i) != null) { - capacity += encodedList.get(i++).length; - } + capacity += KeyUtil.getKeyBytes(eachMkey).length; + capacity += encodedList.get(i++).length; capacity += 64; } @@ -188,18 +184,16 @@ public ByteBuffer getAsciiCommand() { ByteBuffer bb = ByteBuffer.allocate(capacity); // create ascii operation string - i = 0; - - Iterator> iterator = mapElements.iterator(); - while (iterator.hasNext()) { - MapElement mapElement = iterator.next(); - value = encodedList.get(i++); + int mkeySize = elements.keySet().size(); + List keyList = new ArrayList(elements.keySet()); + for (i = this.nextOpIndex; i < mkeySize; i++) { + String mkey = keyList.get(i); + value = encodedList.get(i); b = new StringBuilder(); - setArguments(bb, COMMAND, key, - String.valueOf(mapElement.getMkey()), + setArguments(bb, COMMAND, key, mkey, b.toString(), (value == null ? -1 : value.length), - (iterator.hasNext()) ? PIPE : ""); + (i < mkeySize - 1) ? PIPE : ""); if (value != null) { if (value.length > 0) { bb.put(value); diff --git a/src/main/java/net/spy/memcached/collection/CollectionUpdate.java b/src/main/java/net/spy/memcached/collection/CollectionUpdate.java index 403d1edb..89b3e888 100644 --- a/src/main/java/net/spy/memcached/collection/CollectionUpdate.java +++ b/src/main/java/net/spy/memcached/collection/CollectionUpdate.java @@ -42,16 +42,6 @@ public CollectionUpdate(T newValue, ElementFlagUpdate eflagUpdate, boolean norep this.noreply = noreply; } - public CollectionUpdate(T newValue, boolean noreply) { - if (newValue == null) { - throw new IllegalArgumentException( - "newValue must not be null."); - } - - this.newValue = newValue; - this.noreply = noreply; - } - public String stringify() { if (str != null) return str; diff --git a/src/main/java/net/spy/memcached/collection/MapDelete.java b/src/main/java/net/spy/memcached/collection/MapDelete.java index 5475e562..48b32b09 100644 --- a/src/main/java/net/spy/memcached/collection/MapDelete.java +++ b/src/main/java/net/spy/memcached/collection/MapDelete.java @@ -18,7 +18,7 @@ import java.util.List; -public class MapDelete extends CollectionDelete{ +public class MapDelete extends CollectionDelete { private static final String command = "mop delete"; protected List mkeyList; diff --git a/src/main/java/net/spy/memcached/collection/MapElement.java b/src/main/java/net/spy/memcached/collection/MapElement.java deleted file mode 100644 index bd431be7..00000000 --- a/src/main/java/net/spy/memcached/collection/MapElement.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * arcus-java-client : Arcus Java client - * Copyright 2016 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; - -/** - * Collection MapElement - * - * @param - */ -public class MapElement { - private final String mkey; - private final T value; - - /** - * Create an element - * - * @param mkey mkey of mapElement - * @param value value of mapElement - */ - public MapElement(String mkey, T value) { - this.mkey = mkey; - this.value = value; - } - - /** - * get mkey in map op. - * - * @return mkey - */ - public String getMkey() { - return mkey; - } - - /** - * get value - * - * @return value - */ - public T getValue() { - return value; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("{ \""); - sb.append(getMkey()); - - sb.append("\" : { "); - - sb.append(" \"value\" : \"").append(value.toString()).append("\""); - sb.append(" }"); - - return sb.toString(); - } - -} diff --git a/src/main/java/net/spy/memcached/collection/MapUpdate.java b/src/main/java/net/spy/memcached/collection/MapUpdate.java index 9e41643f..afb6084f 100644 --- a/src/main/java/net/spy/memcached/collection/MapUpdate.java +++ b/src/main/java/net/spy/memcached/collection/MapUpdate.java @@ -21,7 +21,7 @@ public class MapUpdate extends CollectionUpdate { private static final String command = "mop update"; public MapUpdate(T newValue, boolean noreply) { - super(newValue, noreply); + super(newValue, null, noreply); } public String getCommand() { diff --git a/src/test/java/net/spy/memcached/ArcusTimeoutTest.java b/src/test/java/net/spy/memcached/ArcusTimeoutTest.java index 64b1d8de..744b79a8 100644 --- a/src/test/java/net/spy/memcached/ArcusTimeoutTest.java +++ b/src/test/java/net/spy/memcached/ArcusTimeoutTest.java @@ -349,21 +349,21 @@ public void testMopInsertBulkMultipleTimeout() String key = "MyMopKey"; String value = "MyValue"; - int mkeySize = mc.getMaxPipedItemCount(); - Map mkeys = new TreeMap(); - for (int i = 0; i < mkeySize; i++) { - mkeys.put(String.valueOf(i), value); + int elementSize = mc.getMaxPipedItemCount(); + Map elements = new TreeMap(); + for (int i = 0; i < elementSize; i++) { + elements.put(String.valueOf(i), value); } Future> future = mc.asyncMopPipedInsertBulk( - key, mkeys, new CollectionAttributes()); + key, elements, new CollectionAttributes()); future.get(1L, TimeUnit.NANOSECONDS); future.cancel(true); } public void testMopInsertBulkTimeout() throws InterruptedException, ExecutionException, TimeoutException { - String key = "MyMopKey"; + String mkey = "MyMopKey"; String value = "MyValue"; int keySize = 250000; @@ -373,7 +373,7 @@ public void testMopInsertBulkTimeout() } Future> future = mc.asyncMopInsertBulk( - Arrays.asList(keys), key, value, new CollectionAttributes()); + Arrays.asList(keys), mkey, value, new CollectionAttributes()); future.get(1L, TimeUnit.MILLISECONDS); future.cancel(true); } diff --git a/src/test/manual/net/spy/memcached/bulkoperation/MopInsertBulkMultipleTest.java b/src/test/manual/net/spy/memcached/bulkoperation/MopInsertBulkMultipleTest.java index 9644894e..2cb9babb 100644 --- a/src/test/manual/net/spy/memcached/bulkoperation/MopInsertBulkMultipleTest.java +++ b/src/test/manual/net/spy/memcached/bulkoperation/MopInsertBulkMultipleTest.java @@ -34,10 +34,10 @@ public void testInsertAndGet() { String key = "MyMopKey32"; String value = "MyValue"; - int mkeySize = 500; - Map mkeys = new TreeMap(); - for (int i = 0; i < mkeySize; i++) { - mkeys.put(String.valueOf(i), value); + int elementSize = 500; + Map elements = new TreeMap(); + for (int i = 0; i < elementSize; i++) { + elements.put(String.valueOf(i), value); } try { @@ -46,7 +46,7 @@ public void testInsertAndGet() { // SET Future> future = mc - .asyncMopPipedInsertBulk(key, mkeys, + .asyncMopPipedInsertBulk(key, elements, new CollectionAttributes()); try { Map errorList = future.get( @@ -61,7 +61,7 @@ public void testInsertAndGet() { // GET int errorCount = 0; - for (Entry entry : mkeys.entrySet()) { + for (Entry entry : elements.entrySet()) { Future> f = mc.asyncMopGet(key, entry.getKey(), false, false); Map map = null; @@ -79,65 +79,7 @@ public void testInsertAndGet() { Assert.assertEquals("Error count is greater than 0.", 0, errorCount); // REMOVE - for (Entry entry : mkeys.entrySet()) { - mc.asyncMopDelete(key, entry.getKey(), true).get(); - } - } catch (Exception e) { - e.printStackTrace(); - Assert.fail(); - } - } - - public void testInsertAndGetUsingSingleClient() { - String key = "MyMopKey333"; - String value = "MyValue"; - - int mkeySize = 500; - Map mkeys = new TreeMap(); - for (int i = 0; i < mkeySize; i++) { - mkeys.put(String.valueOf(i), value); - } - - try { - // REMOVE - mc.asyncMopDelete(key, true); - - // SET - Future> future = mc - .asyncMopPipedInsertBulk(key, mkeys, - new CollectionAttributes()); - try { - Map errorList = future.get( - 20000L, TimeUnit.MILLISECONDS); - - Assert.assertTrue("Error list is not empty.", - errorList.isEmpty()); - } catch (TimeoutException e) { - future.cancel(true); - e.printStackTrace(); - } - - // GET - int errorCount = 0; - for (Entry entry : mkeys.entrySet()) { - Future> f = mc.asyncMopGet(key, - entry.getKey(), false, false); - Map map = null; - try { - map = f.get(); - } catch (Exception e) { - f.cancel(true); - e.printStackTrace(); - } - Object value2 = map.entrySet().iterator().next().getValue(); - if (!value.equals(value2)) { - errorCount++; - } - } - Assert.assertEquals("Error count is greater than 0.", 0, errorCount); - - // REMOVE - for (Entry entry : mkeys.entrySet()) { + for (Entry entry : elements.entrySet()) { mc.asyncMopDelete(key, entry.getKey(), true).get(); } } catch (Exception e) { @@ -150,10 +92,10 @@ public void testErrorCount() { String key = "MyMopKeyErrorCount"; String value = "MyValue"; - int mkeySize = 1200; - Map mkeys = new TreeMap(); - for (int i = 0; i < mkeySize; i++) { - mkeys.put(String.valueOf(i), value); + int elementSize = 1200; + Map elements = new TreeMap(); + for (int i = 0; i < elementSize; i++) { + elements.put(String.valueOf(i), value); } try { @@ -161,11 +103,11 @@ public void testErrorCount() { // SET Future> future = mc - .asyncMopPipedInsertBulk(key, mkeys, null); + .asyncMopPipedInsertBulk(key, elements, null); Map map = future.get(2000L, TimeUnit.MILLISECONDS); - assertEquals(mkeySize, map.size()); + assertEquals(elementSize, map.size()); } catch (Exception e) { e.printStackTrace(); diff --git a/src/test/manual/net/spy/memcached/bulkoperation/PipeInsertTest.java b/src/test/manual/net/spy/memcached/bulkoperation/PipeInsertTest.java index eee375cd..02fa827a 100644 --- a/src/test/manual/net/spy/memcached/bulkoperation/PipeInsertTest.java +++ b/src/test/manual/net/spy/memcached/bulkoperation/PipeInsertTest.java @@ -58,8 +58,6 @@ public void testBopPipeInsert() { } try { - long start = System.currentTimeMillis(); - CollectionAttributes attr = new CollectionAttributes(); CollectionFuture> future = mc @@ -68,8 +66,6 @@ public void testBopPipeInsert() { Map map = future.get(5000L, TimeUnit.MILLISECONDS); - // System.out.println(System.currentTimeMillis() - start + "ms"); - Assert.assertTrue(map.isEmpty()); Map> map3 = mc.asyncBopGet(KEY, 0, 9999, @@ -160,8 +156,6 @@ public void testMopPipeInsert() { } try { - long start = System.currentTimeMillis(); - CollectionAttributes attr = new CollectionAttributes(); CollectionFuture> future = mc @@ -170,8 +164,6 @@ public void testMopPipeInsert() { Map map = future.get(5000L, TimeUnit.MILLISECONDS); - // System.out.println(System.currentTimeMillis() - start + "ms"); - Assert.assertEquals(1000, map.size()); Map rmap = mc.asyncMopGet(KEY, false, false) diff --git a/src/test/manual/net/spy/memcached/collection/map/MopBulkAPITest.java b/src/test/manual/net/spy/memcached/collection/map/MopBulkAPITest.java index 9616da2b..9ea4f81f 100644 --- a/src/test/manual/net/spy/memcached/collection/map/MopBulkAPITest.java +++ b/src/test/manual/net/spy/memcached/collection/map/MopBulkAPITest.java @@ -20,14 +20,11 @@ import net.spy.memcached.collection.BaseIntegrationTest; import net.spy.memcached.collection.CollectionAttributes; import net.spy.memcached.collection.CollectionOverflowAction; -import net.spy.memcached.collection.MapElement; import net.spy.memcached.internal.CollectionFuture; import net.spy.memcached.ops.CollectionOperationStatus; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; import java.util.Map; +import java.util.HashMap; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -35,7 +32,7 @@ public class MopBulkAPITest extends BaseIntegrationTest { private String key = "MopBulkAPITest33"; Map elements = new HashMap(); - List> updateMap = new ArrayList>(); + Map updateMap = new HashMap(); private int getValueCount() { @@ -47,10 +44,8 @@ protected void setUp() throws Exception { for (long i = 0; i < getValueCount(); i++) { elements.put("mkey" + String.valueOf(i), "value" + String.valueOf(i)); - MapElement temp = - new MapElement("mkey" + String.valueOf(i), - "newvalue" + String.valueOf(i)); - updateMap.add(temp); + updateMap.put("mkey" + String.valueOf(i), + "newvalue" + String.valueOf(i)); } }