You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2014/04/12 00:21:29 UTC
[3/7] git commit: Refactored cache and shard allocation to seperate
concerns
Refactored cache and shard allocation to seperate concerns
Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/ed2e63be
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/ed2e63be
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/ed2e63be
Branch: refs/heads/asyncqueue
Commit: ed2e63beea3f3b0726e9f892b7038efe52a5bd12
Parents: c9975aa
Author: Todd Nine <tn...@apigee.com>
Authored: Fri Apr 4 11:41:30 2014 -0700
Committer: Todd Nine <tn...@apigee.com>
Committed: Fri Apr 4 11:41:30 2014 -0700
----------------------------------------------------------------------
.../graph/impl/cache/NodeShardAllocation.java | 81 +++++++++
.../graph/impl/cache/NodeShardCacheImpl.java | 64 +++----
.../graph/impl/cache/NodeShardCacheTest.java | 173 +++++++++++++++----
3 files changed, 246 insertions(+), 72 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ed2e63be/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardAllocation.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardAllocation.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardAllocation.java
new file mode 100644
index 0000000..8bc4f6c
--- /dev/null
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardAllocation.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.usergrid.persistence.graph.impl.cache;
+
+
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.collection.OrganizationScope;
+import org.apache.usergrid.persistence.model.entity.Id;
+
+
+
+public interface NodeShardAllocation {
+
+ public static final UUID MIN_UUID = new UUID( 0, 1 );
+
+ /**
+ * Get all shards for the given info. If none exist, a default shard should be allocated
+ * @param scope
+ * @param nodeId
+ * @param edgeTypes
+ * @return A list of all shards <= the current shard. This will always return MIN_UUID if no shards are allocated
+ */
+ public List<UUID> getShards(final OrganizationScope scope, final Id nodeId, final String... edgeTypes);
+
+
+ /**
+ * Audit our highest shard for it's maximum capacity. If it has reached the max capacity <=, it will allocate a new shard
+ *
+ * @param scope The organization scope
+ * @param nodeId The node id
+ * @param edgeType The edge types
+ * @return True if a new shard was allocated
+ */
+ public boolean auditMaxShard(final OrganizationScope scope, final Id nodeId, final String... edgeType);
+
+ /**
+ * The minimum uuid we allocate
+ */
+// private static final UUID MIN_UUID = new UUID( 0, 1 );
+//
+
+ /**
+ *
+ * There are no shards allocated, allocate the minimum shard
+ */
+ /**
+ *
+ *
+ if(shards == null || shards.size() == 0){
+
+ try {
+ edgeSeriesSerialization.writeEdgeMeta( scope, nodeId, MIN_UUID, edgeType ).execute();
+ }
+ catch ( ConnectionException e ) {
+ throw new RuntimeException("Unable to write edge meta data", e);
+ }
+
+ return MIN_UUID;
+ }
+
+ (**/
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ed2e63be/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardCacheImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardCacheImpl.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardCacheImpl.java
index b75cd19..1c373af 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardCacheImpl.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardCacheImpl.java
@@ -33,6 +33,7 @@ import org.apache.usergrid.persistence.collection.OrganizationScope;
import org.apache.usergrid.persistence.graph.GraphFig;
import org.apache.usergrid.persistence.graph.serialization.EdgeSeriesSerialization;
import org.apache.usergrid.persistence.model.entity.Id;
+import org.apache.usergrid.persistence.model.util.UUIDGenerator;
import com.fasterxml.uuid.UUIDComparator;
import com.google.common.cache.CacheBuilder;
@@ -48,12 +49,9 @@ import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
*/
public class NodeShardCacheImpl implements NodeShardCache {
- /**
- * The minimum uuid we allocate
- */
- private static final UUID MIN_UUID = new UUID( 0, 1 );
- private final EdgeSeriesSerialization edgeSeriesSerialization;
+
+ private final NodeShardAllocation nodeShardAllocation;
private final GraphFig graphFig;
private LoadingCache<CacheKey, CacheEntry> graphs;
@@ -61,12 +59,12 @@ public class NodeShardCacheImpl implements NodeShardCache {
/**
*
- * @param edgeSeriesSerialization
+ * @param nodeShardAllocation
* @param graphFig
*/
@Inject
- public NodeShardCacheImpl( final EdgeSeriesSerialization edgeSeriesSerialization, final GraphFig graphFig ) {
- this.edgeSeriesSerialization = edgeSeriesSerialization;
+ public NodeShardCacheImpl( final NodeShardAllocation nodeShardAllocation, final GraphFig graphFig ) {
+ this.nodeShardAllocation = nodeShardAllocation;
this.graphFig = graphFig;
/**
@@ -104,27 +102,13 @@ public class NodeShardCacheImpl implements NodeShardCache {
throw new RuntimeException( "Unable to load cache key for graph", e );
}
- List<UUID> shards = entry.getShardId(time, 1 );
-
- if(shards == null || shards.size() == 0){
-
- try {
- edgeSeriesSerialization.writeEdgeMeta( scope, nodeId, MIN_UUID, edgeType ).execute();
- }
- catch ( ConnectionException e ) {
- throw new RuntimeException("Unable to write edge meta data", e);
- }
-
- return MIN_UUID;
- }
-
- final UUID shardId = entry.getShardId(time, 1).get( 0 );
+ final UUID shardId = entry.getShardId(time);
if(shardId != null){
return shardId;
}
- //if we get here, something went wrong, our cache should always have a min time UUID.
+ //if we get here, something went wrong, our cache should always have a time UUID to return to us
throw new RuntimeException( "No time UUID shard was found and could not allocate one" );
}
@@ -144,8 +128,14 @@ public class NodeShardCacheImpl implements NodeShardCache {
@Override
public CacheEntry load( final CacheKey key ) throws Exception {
- final List<UUID> edges = edgeSeriesSerialization
- .getEdgeMetaData( key.scope, key.id, key.types );
+ final List<UUID> edges = nodeShardAllocation.getShards( key.scope,
+ key.id, key.types );
+
+
+ /**
+ * Perform an async audit
+ */
+ nodeShardAllocation.auditMaxShard( key.scope, key.id, key.types );
return new CacheEntry( edges );
}
@@ -218,44 +208,34 @@ public class NodeShardCacheImpl implements NodeShardCache {
/**
* Get the shard's UUID for the uuid we're attempting to seek from
+ *
* @param seek
* @return
*/
- public List<UUID> getShardId( final UUID seek, final int size) {
+ public UUID getShardId( final UUID seek) {
int index = Collections.binarySearch( this.shards, seek, MetaComparator.INSTANCE );
/**
* We have an exact match, return it
*/
if(index > -1){
- return getShards(index, size);
+ return shards.get( index );
}
//update the index to represent the index we should insert to and read it. This will be <= the UUID we were passed
- index = index*-1+1;
+ //we subtract 2 to get the index < this one
+ index = (index*-1) -2;
if(index < shards.size()){
- return getShards( index, size );
+ return shards.get( index );
}
return null;
}
- /**
- * Get the ordered list of shards from high to low
- * @param index
- * @param size
- * @return
- */
- private List<UUID> getShards(final int index, final int size){
- int toIndex = Math.min( shards.size(), index+size );
- return shards.subList(index, toIndex );
- }
-
-
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ed2e63be/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardCacheTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardCacheTest.java b/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardCacheTest.java
index 96787be..9ea684e 100644
--- a/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardCacheTest.java
+++ b/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/impl/cache/NodeShardCacheTest.java
@@ -19,6 +19,7 @@
package org.apache.usergrid.persistence.graph.impl.cache;
+import java.util.Arrays;
import java.util.Collections;
import java.util.UUID;
@@ -27,8 +28,6 @@ import org.junit.Test;
import org.apache.usergrid.persistence.collection.OrganizationScope;
import org.apache.usergrid.persistence.graph.GraphFig;
-import org.apache.usergrid.persistence.graph.serialization.EdgeSerialization;
-import org.apache.usergrid.persistence.graph.serialization.EdgeSeriesSerialization;
import org.apache.usergrid.persistence.model.entity.Id;
import org.apache.usergrid.persistence.model.util.UUIDGenerator;
@@ -37,8 +36,6 @@ import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
import static org.apache.usergrid.persistence.graph.test.util.EdgeTestUtils.createId;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -51,7 +48,6 @@ import static org.mockito.Mockito.when;
public class NodeShardCacheTest {
-
protected OrganizationScope scope;
@@ -73,72 +69,189 @@ public class NodeShardCacheTest {
final GraphFig graphFig = getFigMock();
- final EdgeSeriesSerialization serialization = mock( EdgeSeriesSerialization.class );
+ final NodeShardAllocation allocation = mock( NodeShardAllocation.class );
- final Id id = createId("test");
+ final Id id = createId( "test" );
final String edgeType = "edge";
final String otherIdType = "type";
+ UUID newTime = UUIDGenerator.newTimeUUID();
+ NodeShardCache cache = new NodeShardCacheImpl( allocation, graphFig );
- UUID newTime = UUIDGenerator.newTimeUUID();
+ /**
+ * Simulate returning no shards at all.
+ */
+ when( allocation.getShards( same( scope ), same( id ), same( edgeType ), same( otherIdType ) ) )
+ .thenReturn( Collections.singletonList( NodeShardAllocation.MIN_UUID ) );
+ UUID slice = cache.getSlice( scope, id, newTime, edgeType, otherIdType );
+
- NodeShardCache cache = new NodeShardCacheImpl(serialization, graphFig );
+ //we return the min UUID possible, all edges should start by writing to this edge
+ assertEquals( NodeShardAllocation.MIN_UUID, slice );
/**
- * Simulate returning no shards at all.
+ * Verify that we fired the audit
*/
- when(serialization.getEdgeMetaData( same(scope), same(id), same(edgeType), same(otherIdType) )).thenReturn(
- Collections.<UUID>emptyList() );
+ verify( allocation ).auditMaxShard( scope, id, edgeType, otherIdType );
+ }
- final MutationBatch batch = mock(MutationBatch.class);
+ @Test
+ public void testSingleExistingShard() {
+
+ final GraphFig graphFig = getFigMock();
- //mock up returning the mutation batch
- when(serialization.writeEdgeMeta( same( scope ), same( id ), any( UUID.class ), same(edgeType), same(otherIdType))).thenReturn( batch );
+ final NodeShardAllocation allocation = mock( NodeShardAllocation.class );
+
+
+ final Id id = createId( "test" );
+
+ final String edgeType = "edge";
+
+ final String otherIdType = "type";
+
+
+ UUID newTime = UUIDGenerator.newTimeUUID();
+
+ final UUID min = new UUID( 0, 1 );
+
+
+ NodeShardCache cache = new NodeShardCacheImpl( allocation, graphFig );
+
+
+ /**
+ * Simulate returning single shard
+ */
+ when( allocation.getShards( same( scope ), same( id ), same( edgeType ), same( otherIdType ) ) )
+ .thenReturn( Collections.singletonList( min ) );
- final UUID min = new UUID(0, 1);
UUID slice = cache.getSlice( scope, id, newTime, edgeType, otherIdType );
//we return the min UUID possible, all edges should start by writing to this edge
- assertEquals(min, slice);
+ assertEquals( min, slice );
+
+ /**
+ * Verify that we fired the audit
+ */
+ verify( allocation ).auditMaxShard( scope, id, edgeType, otherIdType );
+ }
+
+
+ @Test
+ public void testRangeShard() {
+
+ final GraphFig graphFig = getFigMock();
+
+ final NodeShardAllocation allocation = mock( NodeShardAllocation.class );
+
+ final Id id = createId( "test" );
+
+ final String edgeType = "edge";
+
+ final String otherIdType = "type";
+
/**
- * Verify that we
+ * Set our min mid and max
*/
- verify( serialization).writeEdgeMeta( scope, id, slice, edgeType, otherIdType);
+ final UUID min = new UUID( 0, 1 );
+
+
+ final UUID mid = new UUID( 0, 100 );
+
+
+ final UUID max = new UUID( 0, 200 );
+
+
+ NodeShardCache cache = new NodeShardCacheImpl( allocation, graphFig );
+
/**
- * Verify that execute was invoked
+ * Simulate returning all shards
*/
- verify(batch).execute();
+ when( allocation.getShards( same( scope ), same( id ), same( edgeType ), same( otherIdType ) ) )
+ .thenReturn( Arrays.asList( min, mid, max ) );
- }
+ //check getting equal to our min, mid and max
+ UUID slice = cache.getSlice( scope, id, new UUID( min.getMostSignificantBits(), min.getLeastSignificantBits() ),
+ edgeType, otherIdType );
+
+
+ //we return the min UUID possible, all edges should start by writing to this edge
+ assertEquals( min, slice );
+
+ slice = cache.getSlice( scope, id, new UUID( mid.getMostSignificantBits(), mid.getLeastSignificantBits() ),
+ edgeType, otherIdType );
+
+
+ //we return the mid UUID possible, all edges should start by writing to this edge
+ assertEquals( mid, slice );
+
+ slice = cache.getSlice( scope, id, new UUID( max.getMostSignificantBits(), max.getLeastSignificantBits() ),
+ edgeType, otherIdType );
+
+
+ //we return the mid UUID possible, all edges should start by writing to this edge
+ assertEquals( max, slice );
+
+ //now test in between
+ slice = cache.getSlice( scope, id, new UUID( 0, 1 ), edgeType, otherIdType );
- @Test
- public void testExistingShard(){
- fail("TODO");
+ //we return the min UUID possible, all edges should start by writing to this edge
+ assertEquals( min, slice );
+
+ slice = cache.getSlice( scope, id, new UUID( 0, 99 ), edgeType, otherIdType );
+
+
+ //we return the min UUID possible, all edges should start by writing to this edge
+ assertEquals( min, slice );
+
+
+ slice = cache.getSlice( scope, id, new UUID( 0, 101 ), edgeType, otherIdType );
+
+
+ //we return the mid UUID possible, all edges should start by writing to this edge
+ assertEquals( mid, slice );
+
+ slice = cache.getSlice( scope, id, new UUID( 0, 199 ), edgeType, otherIdType );
+
+
+ //we return the mid UUID possible, all edges should start by writing to this edge
+ assertEquals( mid, slice );
+
+
+ slice = cache.getSlice( scope, id, new UUID( 0, 201 ), edgeType, otherIdType );
+
+
+ //we return the mid UUID possible, all edges should start by writing to this edge
+ assertEquals( max, slice );
+
+ /**
+ * Verify that we fired the audit
+ */
+ verify( allocation ).auditMaxShard( scope, id, edgeType, otherIdType );
}
- private GraphFig getFigMock(){
- final GraphFig graphFig = mock( GraphFig.class);
- when(graphFig.getCacheSize()).thenReturn( 1000 );
- when(graphFig.getCacheTimeout()).thenReturn( 30000l );
+
+ private GraphFig getFigMock() {
+ final GraphFig graphFig = mock( GraphFig.class );
+ when( graphFig.getCacheSize() ).thenReturn( 1000 );
+ when( graphFig.getCacheTimeout() ).thenReturn( 30000l );
return graphFig;
}
-
}