Permalink
Browse files

Implemented mutate with Cas operations

  • Loading branch information...
1 parent c83df00 commit 5b3e829ef9491923d2eb3c28e4be8551ac220ee8 @johnzablocki johnzablocki committed Apr 16, 2012
@@ -27,11 +27,19 @@ public interface IMemcachedResultsClient
IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta);
IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt);
IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor);
+
+ IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, ulong cas);
+ IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt, ulong cas);
+ IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor, ulong cas);
IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta);
IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt);
IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor);
+ IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, ulong cas);
+ IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt, ulong cas);
+ IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor, ulong cas);
+
IConcatOperationResult ExecuteAppend(string key, ArraySegment<byte> data);
IConcatOperationResult ExecuteAppend(string key, ulong cas, ArraySegment<byte> data);
@@ -190,6 +190,50 @@ public IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, u
}
/// <summary>
+ /// Increments the value of the specified key by the given amount, but only if the item's version matches the CAS value provided. The operation is atomic and happens on the server.
+ /// </summary>
+ /// <param name="key">The key used to reference the item.</param>
+ /// <param name="defaultValue">The value which will be stored by the server if the specified item was not found.</param>
+ /// <param name="delta">The amount by which the client wants to increase the item.</param>
+ /// <param name="cas">The cas value which must match the item's version.</param>
+ /// <returns>The new value of the item or defaultValue if the key was not found.</returns>
+ /// <remarks>If the client uses the Text protocol, the item must be inserted into the cache before it can be changed. It must be inserted as a <see cref="T:System.String"/>. Moreover the Text protocol only works with <see cref="System.UInt32"/> values, so return value -1 always indicates that the item was not found.</remarks>
+ public IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, ulong cas)
+ {
+ return this.CasMutate(MutationMode.Increment, key, defaultValue, delta, 0, cas);
+ }
+
+ /// <summary>
+ /// Increments the value of the specified key by the given amount, but only if the item's version matches the CAS value provided. The operation is atomic and happens on the server.
+ /// </summary>
+ /// <param name="key">The key used to reference the item.</param>
+ /// <param name="defaultValue">The value which will be stored by the server if the specified item was not found.</param>
+ /// <param name="delta">The amount by which the client wants to increase the item.</param>
+ /// <param name="validFor">The interval after the item is invalidated in the cache.</param>
+ /// <param name="cas">The cas value which must match the item's version.</param>
+ /// <returns>The new value of the item or defaultValue if the key was not found.</returns>
+ /// <remarks>If the client uses the Text protocol, the item must be inserted into the cache before it can be changed. It must be inserted as a <see cref="T:System.String"/>. Moreover the Text protocol only works with <see cref="System.UInt32"/> values, so return value -1 always indicates that the item was not found.</remarks>
+ public IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor, ulong cas)
+ {
+ return this.CasMutate(MutationMode.Increment, key, defaultValue, delta, MemcachedClient.GetExpiration(validFor, null), cas);
+ }
+
+ /// <summary>
+ /// Increments the value of the specified key by the given amount, but only if the item's version matches the CAS value provided. The operation is atomic and happens on the server.
+ /// </summary>
+ /// <param name="key">The key used to reference the item.</param>
+ /// <param name="defaultValue">The value which will be stored by the server if the specified item was not found.</param>
+ /// <param name="delta">The amount by which the client wants to increase the item.</param>
+ /// <param name="expiresAt">The time when the item is invalidated in the cache.</param>
+ /// <param name="cas">The cas value which must match the item's version.</param>
+ /// <returns>The new value of the item or defaultValue if the key was not found.</returns>
+ /// <remarks>If the client uses the Text protocol, the item must be inserted into the cache before it can be changed. It must be inserted as a <see cref="T:System.String"/>. Moreover the Text protocol only works with <see cref="System.UInt32"/> values, so return value -1 always indicates that the item was not found.</remarks>
+ public IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt, ulong cas)
+ {
+ return this.CasMutate(MutationMode.Increment, key, defaultValue, delta, MemcachedClient.GetExpiration(null, expiresAt), cas);
+ }
+
+ /// <summary>
/// Decrements the value of the specified key by the given amount. The operation is atomic and happens on the server.
/// </summary>
/// <param name="key">The key used to reference the item.</param>
@@ -229,6 +273,50 @@ public IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, u
{
return this.PerformMutate(MutationMode.Decrement, key, defaultValue, delta, MemcachedClient.GetExpiration(null, expiresAt));
}
+
+ /// <summary>
+ /// Decrements the value of the specified key by the given amount, but only if the item's version matches the CAS value provided. The operation is atomic and happens on the server.
+ /// </summary>
+ /// <param name="key">The key used to reference the item.</param>
+ /// <param name="defaultValue">The value which will be stored by the server if the specified item was not found.</param>
+ /// <param name="delta">The amount by which the client wants to decrease the item.</param>
+ /// <param name="cas">The cas value which must match the item's version.</param>
+ /// <returns>The new value of the item or defaultValue if the key was not found.</returns>
+ /// <remarks>If the client uses the Text protocol, the item must be inserted into the cache before it can be changed. It must be inserted as a <see cref="T:System.String"/>. Moreover the Text protocol only works with <see cref="System.UInt32"/> values, so return value -1 always indicates that the item was not found.</remarks>
+ public IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, ulong cas)
+ {
+ return this.CasMutate(MutationMode.Decrement, key, defaultValue, delta, 0, cas);
+ }
+
+ /// <summary>
+ /// Decrements the value of the specified key by the given amount, but only if the item's version matches the CAS value provided. The operation is atomic and happens on the server.
+ /// </summary>
+ /// <param name="key">The key used to reference the item.</param>
+ /// <param name="defaultValue">The value which will be stored by the server if the specified item was not found.</param>
+ /// <param name="delta">The amount by which the client wants to decrease the item.</param>
+ /// <param name="validFor">The interval after the item is invalidated in the cache.</param>
+ /// <param name="cas">The cas value which must match the item's version.</param>
+ /// <returns>The new value of the item or defaultValue if the key was not found.</returns>
+ /// <remarks>If the client uses the Text protocol, the item must be inserted into the cache before it can be changed. It must be inserted as a <see cref="T:System.String"/>. Moreover the Text protocol only works with <see cref="System.UInt32"/> values, so return value -1 always indicates that the item was not found.</remarks>
+ public IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor, ulong cas)
+ {
+ return this.CasMutate(MutationMode.Decrement, key, defaultValue, delta, MemcachedClient.GetExpiration(validFor, null), cas);
+ }
+
+ /// <summary>
+ /// Decrements the value of the specified key by the given amount, but only if the item's version matches the CAS value provided. The operation is atomic and happens on the server.
+ /// </summary>
+ /// <param name="key">The key used to reference the item.</param>
+ /// <param name="defaultValue">The value which will be stored by the server if the specified item was not found.</param>
+ /// <param name="delta">The amount by which the client wants to decrease the item.</param>
+ /// <param name="expiresAt">The time when the item is invalidated in the cache.</param>
+ /// <param name="cas">The cas value which must match the item's version.</param>
+ /// <returns>The new value of the item or defaultValue if the key was not found.</returns>
+ /// <remarks>If the client uses the Text protocol, the item must be inserted into the cache before it can be changed. It must be inserted as a <see cref="T:System.String"/>. Moreover the Text protocol only works with <see cref="System.UInt32"/> values, so return value -1 always indicates that the item was not found.</remarks>
+ public IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt, ulong cas)
+ {
+ return this.CasMutate(MutationMode.Decrement, key, defaultValue, delta, MemcachedClient.GetExpiration(null, expiresAt), cas);
+ }
#endregion
#region [ Concatenate ]
@@ -443,7 +443,8 @@ public ulong Increment(string key, ulong defaultValue, ulong delta, DateTime exp
/// <remarks>If the client uses the Text protocol, the item must be inserted into the cache before it can be changed. It must be inserted as a <see cref="T:System.String"/>. Moreover the Text protocol only works with <see cref="System.UInt32"/> values, so return value -1 always indicates that the item was not found.</remarks>
public CasResult<ulong> Increment(string key, ulong defaultValue, ulong delta, ulong cas)
{
- return this.CasMutate(MutationMode.Increment, key, defaultValue, delta, 0, cas);
+ var result = this.CasMutate(MutationMode.Increment, key, defaultValue, delta, 0, cas);
+ return new CasResult<ulong> { Cas = result.Cas, Result = result.Value, StatusCode = result.StatusCode.Value };
@AndrewLane

AndrewLane Dec 21, 2012

Isn't it possible for CasMutate to return an object that has StatusCode == null? And this would throw a "nullable object must have a value" exception since we're referencing StatusCode.Value? I'm seeing this locally and I'm not 100% sure I'm not doing something stupid, but I thought I'd ask...

@AndrewLane

AndrewLane Dec 21, 2012

I submitted a pull request and a Couchbase support ticket...

@jzablocki

jzablocki Dec 21, 2012

Yes, that's a great catch. Thanks for submitting this patch. I'll make sure it gets into the next release of the Couchbase client and will merge it into our fork.

}
/// <summary>
@@ -458,7 +459,8 @@ public CasResult<ulong> Increment(string key, ulong defaultValue, ulong delta, u
/// <remarks>If the client uses the Text protocol, the item must be inserted into the cache before it can be changed. It must be inserted as a <see cref="T:System.String"/>. Moreover the Text protocol only works with <see cref="System.UInt32"/> values, so return value -1 always indicates that the item was not found.</remarks>
public CasResult<ulong> Increment(string key, ulong defaultValue, ulong delta, TimeSpan validFor, ulong cas)
{
- return this.CasMutate(MutationMode.Increment, key, defaultValue, delta, MemcachedClient.GetExpiration(validFor, null), cas);
+ var result = this.CasMutate(MutationMode.Increment, key, defaultValue, delta, MemcachedClient.GetExpiration(validFor, null), cas);
+ return new CasResult<ulong> { Cas = result.Cas, Result = result.Value, StatusCode = result.StatusCode.Value };
}
/// <summary>
@@ -473,7 +475,8 @@ public CasResult<ulong> Increment(string key, ulong defaultValue, ulong delta, T
/// <remarks>If the client uses the Text protocol, the item must be inserted into the cache before it can be changed. It must be inserted as a <see cref="T:System.String"/>. Moreover the Text protocol only works with <see cref="System.UInt32"/> values, so return value -1 always indicates that the item was not found.</remarks>
public CasResult<ulong> Increment(string key, ulong defaultValue, ulong delta, DateTime expiresAt, ulong cas)
{
- return this.CasMutate(MutationMode.Increment, key, defaultValue, delta, MemcachedClient.GetExpiration(null, expiresAt), cas);
+ var result = this.CasMutate(MutationMode.Increment, key, defaultValue, delta, MemcachedClient.GetExpiration(null, expiresAt), cas);
+ return new CasResult<ulong> { Cas = result.Cas, Result = result.Value, StatusCode = result.StatusCode.Value };
}
#endregion
@@ -530,7 +533,8 @@ public ulong Decrement(string key, ulong defaultValue, ulong delta, DateTime exp
/// <remarks>If the client uses the Text protocol, the item must be inserted into the cache before it can be changed. It must be inserted as a <see cref="T:System.String"/>. Moreover the Text protocol only works with <see cref="System.UInt32"/> values, so return value -1 always indicates that the item was not found.</remarks>
public CasResult<ulong> Decrement(string key, ulong defaultValue, ulong delta, ulong cas)
{
- return this.CasMutate(MutationMode.Decrement, key, defaultValue, delta, 0, cas) ;
+ var result = this.CasMutate(MutationMode.Decrement, key, defaultValue, delta, 0, cas);
+ return new CasResult<ulong> { Cas = result.Cas, Result = result.Value, StatusCode = result.StatusCode.Value };
}
/// <summary>
@@ -545,7 +549,8 @@ public CasResult<ulong> Decrement(string key, ulong defaultValue, ulong delta, u
/// <remarks>If the client uses the Text protocol, the item must be inserted into the cache before it can be changed. It must be inserted as a <see cref="T:System.String"/>. Moreover the Text protocol only works with <see cref="System.UInt32"/> values, so return value -1 always indicates that the item was not found.</remarks>
public CasResult<ulong> Decrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor, ulong cas)
{
- return this.CasMutate(MutationMode.Decrement, key, defaultValue, delta, MemcachedClient.GetExpiration(validFor, null), cas);
+ var result = this.CasMutate(MutationMode.Decrement, key, defaultValue, delta, MemcachedClient.GetExpiration(validFor, null), cas);
+ return new CasResult<ulong> { Cas = result.Cas, Result = result.Value, StatusCode = result.StatusCode.Value };
}
/// <summary>
@@ -560,7 +565,8 @@ public CasResult<ulong> Decrement(string key, ulong defaultValue, ulong delta, T
/// <remarks>If the client uses the Text protocol, the item must be inserted into the cache before it can be changed. It must be inserted as a <see cref="T:System.String"/>. Moreover the Text protocol only works with <see cref="System.UInt32"/> values, so return value -1 always indicates that the item was not found.</remarks>
public CasResult<ulong> Decrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt, ulong cas)
{
- return this.CasMutate(MutationMode.Decrement, key, defaultValue, delta, MemcachedClient.GetExpiration(null, expiresAt), cas);
+ var result = this.CasMutate(MutationMode.Decrement, key, defaultValue, delta, MemcachedClient.GetExpiration(null, expiresAt), cas);
+ return new CasResult<ulong> { Cas = result.Cas, Result = result.Value, StatusCode = result.StatusCode.Value };
}
#endregion
@@ -572,12 +578,12 @@ private IMutateOperationResult PerformMutate(MutationMode mode, string key, ulon
return PerformMutate(mode, key, defaultValue, delta, expires, ref tmp);
}
- private CasResult<ulong> CasMutate(MutationMode mode, string key, ulong defaultValue, ulong delta, uint expires, ulong cas)
+ private IMutateOperationResult CasMutate(MutationMode mode, string key, ulong defaultValue, ulong delta, uint expires, ulong cas)
{
var tmp = cas;
var retval = PerformMutate(mode, key, defaultValue, delta, expires, ref tmp);
-
- return new CasResult<ulong> { Cas = tmp, Result = retval.Value };
+ retval.Cas = tmp;
+ return retval;
}
protected virtual IMutateOperationResult PerformMutate(MutationMode mode, string key, ulong defaultValue, ulong delta, uint expires, ref ulong cas)

0 comments on commit 5b3e829

Please sign in to comment.