Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: enyim/EnyimMemcached
...
head fork: couchbaselabs/EnyimMemcached
compare: fc2dc64aa7e4a0b95bd1596e106d7d92ad5bd470
  • 8 commits
  • 26 files changed
  • 0 commit comments
  • 3 contributors
Commits on Apr 13, 2011
Jeffry Morris Changed .ctor to correct overload 3b38476
Commits on Apr 17, 2011
@enyim Merge branch 'master' of https://github.com/jeffrymorris/EnyimMemcached
… into jeffrymorris-master

* 'master' of https://github.com/jeffrymorris/EnyimMemcached:
  Changed .ctor to correct overload
fc841ad
Commits on Apr 21, 2011
@enyim Single item implementation of the Sync command. 7cf27fb
@enyim Fix release build. 4563354
@enyim One should write unit tests or review the source code, so waiting for…
… persistence would actually wait for persistence, instead of mutation.
2cfbe98
Commits on May 12, 2011
@enyim Totally kill the hash algo caching, something strange is happening wi…
…th HttpContext.Items
931f31e
@enyim Ignore the proxy port everywhere. 896f585
Commits on May 17, 2011
@farshidce farshidce copied nunit dlls under binaries
copied nunit dlls under binaries
fc2dc64
Showing with 10,779 additions and 76 deletions.
  1. +2 −0  Enyim.Caching/Memcached/IMemcachedNode.cs
  2. +2 −22 Enyim.Caching/Memcached/Locators/KetamaNodeLocator.cs
  3. +34 −23 Enyim.Caching/Memcached/MemcachedNode.cs
  4. +6 −2 Enyim.Caching/Memcached/PooledSocket.cs
  5. +18 −2 Enyim.Caching/Memcached/Protocol/Binary/BinaryConverter.cs
  6. +2 −3 Enyim.Caching/Memcached/Protocol/Binary/BinaryNode.cs
  7. +2 −2 Enyim.Caching/Memcached/Protocol/Binary/BinaryResponse.cs
  8. +10 −0 Enyim.Caching/Memcached/Protocol/Binary/BinarySingleItemOperation.cs
  9. +13 −0 Enyim.Caching/Memcached/Protocol/Operation.cs
  10. +6 −0 Membase/BasicMembaseOperationFactory.cs
  11. +1 −0  Membase/Configuration/IMembaseClientConfiguration.cs
  12. +2 −0  Membase/Configuration/MembaseClientConfiguration.cs
  13. +1 −0  Membase/Configuration/MembaseClientSection.cs
  14. +1 −0  Membase/Configuration/ServersElement.cs
  15. +1 −0  Membase/IMembaseOperationFactory.cs
  16. +1 −0  Membase/Membase.csproj
  17. +34 −1 Membase/MembaseClient.cs
  18. +2 −5 Membase/MembasePool.cs
  19. +212 −0 Membase/Operations/SyncOperation.cs
  20. +5 −0 Membase/VBucketAwareOperationFactory.cs
  21. +8 −13 MemcachedTest/KetamaTest.cs
  22. +8 −2 MemcachedTest/MemcachedTest.csproj
  23. BIN  binaries/nunit/framework/nunit.framework.dll
  24. +10,407 −0 binaries/nunit/framework/nunit.framework.xml
  25. BIN  binaries/nunit/framework/nunit.mocks.dll
  26. +1 −1  build/VersionInfo.targets
View
2  Enyim.Caching/Memcached/IMemcachedNode.cs
@@ -12,6 +12,8 @@ public interface IMemcachedNode : IDisposable
bool Ping();
bool Execute(IOperation op);
+ bool Execute(PooledSocket socket, IOperation op);
+ PooledSocket CreateSocket(TimeSpan connectionTimeout, TimeSpan receiveTimeout);
event Action<IMemcachedNode> Failed;
View
24 Enyim.Caching/Memcached/Locators/KetamaNodeLocator.cs
@@ -60,7 +60,7 @@ void IMemcachedNodeLocator.Initialize(IList<IMemcachedNode> nodes)
// sizeof(uint)
const int KeyLength = 4;
- var hashAlgo = this.CreateHash();
+ var hashAlgo = this.factory();
int PartCount = hashAlgo.HashSize / 8 / KeyLength; // HashSize is in bits, uint is 4 bytes long
if (PartCount < 1) throw new ArgumentOutOfRangeException("The hash algorithm must provide at least 32 bits long hashes");
@@ -111,7 +111,7 @@ void IMemcachedNodeLocator.Initialize(IList<IMemcachedNode> nodes)
private uint GetKeyHash(string key)
{
- var hashAlgo = this.CreateHash();
+ var hashAlgo = this.factory();
var uintHash = hashAlgo as IUIntHashAlgorithm;
var keyData = Encoding.UTF8.GetBytes(key);
@@ -241,26 +241,6 @@ private class LookupData
{ "oneatatime", () => new HashkitOneAtATime() }
};
-
- [ThreadStatic]
- private static HashAlgorithm currentAlgo;
-
- private HashAlgorithm CreateHash()
- {
- // we cache the HashAlgorithm instance per thread
- // they are reinitialized before every ComputeHash but we avoid creating then GCing them every time we need
- // to find something (which will happen a lot)
- var ctx = HttpContext.Current;
- if (ctx == null)
- return currentAlgo ?? (currentAlgo = this.factory());
-
- var algo = ctx.Items["**VBucket.CurrentAlgo"] as HashAlgorithm;
- if (algo == null)
- ctx.Items["**VBucket.CurrentAlgo"] = algo = this.factory();
-
- return algo;
- }
-
#endregion
}
}
View
57 Enyim.Caching/Memcached/MemcachedNode.cs
@@ -456,9 +456,14 @@ int IEqualityComparer<IMemcachedNode>.GetHashCode(IMemcachedNode obj)
}
#endregion
- protected internal virtual PooledSocket CreateSocket()
+ protected internal PooledSocket CreateSocket()
{
- PooledSocket retval = new PooledSocket(this.endPoint, this.config.ConnectionTimeout, this.config.ReceiveTimeout);
+ return this.CreateSocket(this.endPoint, this.config.ConnectionTimeout, this.config.ReceiveTimeout);
+ }
+
+ protected internal virtual PooledSocket CreateSocket(IPEndPoint endpoint, TimeSpan connectionTimeout, TimeSpan receiveTimeout)
+ {
+ PooledSocket retval = new PooledSocket(endPoint, connectionTimeout, receiveTimeout);
return retval;
}
@@ -467,20 +472,26 @@ protected virtual bool ExecuteOperation(IOperation op)
{
using (var ps = this.Acquire())
{
- try
- {
- if (ps == null) return false;
+ return this.ExecuteOperation(ps, op);
+ }
+ }
- ps.Write(op.GetBuffer());
+ protected virtual bool ExecuteOperation(PooledSocket socket, IOperation op)
+ {
+ try
+ {
+ if (socket == null) return false;
+ var b = op.GetBuffer();
- return op.ReadResponse(ps);
- }
- catch (Exception e)
- {
- log.Error(e);
+ socket.Write(b);
- return false;
- }
+ return op.ReadResponse(socket);
+ }
+ catch (Exception e)
+ {
+ log.Error(e);
+
+ return false;
}
}
@@ -506,22 +517,22 @@ bool IMemcachedNode.Execute(IOperation op)
return this.ExecuteOperation(op);
}
- //IAsyncResult IMemcachedNode.BeginExecute(IOperation op, AsyncCallback callback, object state)
- //{
- // throw new NotImplementedException();
- //}
-
- //bool IMemcachedNode.EndExecute(IAsyncResult result)
- //{
- // throw new NotImplementedException();
- //}
-
event Action<IMemcachedNode> IMemcachedNode.Failed
{
add { this.Failed += value; }
remove { this.Failed -= value; }
}
+ bool IMemcachedNode.Execute(PooledSocket socket, IOperation op)
+ {
+ return this.ExecuteOperation(socket, op);
+ }
+
+ PooledSocket IMemcachedNode.CreateSocket(TimeSpan connectionTimeout, TimeSpan receiveTimeout)
+ {
+ return this.CreateSocket(this.endPoint, connectionTimeout, receiveTimeout);
+ }
+
#endregion
}
}
View
8 Enyim.Caching/Memcached/PooledSocket.cs
@@ -32,8 +32,12 @@ public PooledSocket(IPEndPoint endpoint, TimeSpan connectionTimeout, TimeSpan re
? Timeout.Infinite
: (int)connectionTimeout.TotalMilliseconds;
- socket.ReceiveTimeout = (int)receiveTimeout.TotalMilliseconds;
- socket.SendTimeout = (int)receiveTimeout.TotalMilliseconds;
+ var rcv = receiveTimeout == TimeSpan.MaxValue
+ ? Timeout.Infinite
+ : (int)receiveTimeout.TotalMilliseconds;
+
+ socket.ReceiveTimeout = rcv;
+ socket.SendTimeout = rcv;
socket.BeginConnect(endpoint, iar =>
{
View
20 Enyim.Caching/Memcached/Protocol/Binary/BinaryConverter.cs
@@ -5,9 +5,9 @@ namespace Enyim.Caching.Memcached.Protocol.Binary
{
public static class BinaryConverter
{
- public static unsafe int DecodeInt16(byte* buffer, int offset)
+ public static unsafe ushort DecodeUInt16(byte* buffer, int offset)
{
- return ((int)(buffer[offset]) << 8) + buffer[offset + 1];
+ return (ushort)((buffer[offset] << 8) + buffer[offset + 1]);
}
public static unsafe int DecodeInt32(ArraySegment<byte> segment, int offset)
@@ -45,6 +45,22 @@ public static unsafe ulong DecodeUInt64(byte* buffer, int offset)
return (ulong)(((long)part2) | (part1 << 32));
}
+ public static unsafe void EncodeUInt16(uint value, byte[] buffer, int offset)
+ {
+ fixed (byte* bufferPtr = buffer)
+ {
+ EncodeUInt16(value, bufferPtr, offset);
+ }
+ }
+
+ public static unsafe void EncodeUInt16(uint value, byte* buffer, int offset)
+ {
+ byte* ptr = buffer + offset;
+
+ ptr[0] = (byte)(value >> 8);
+ ptr[1] = (byte)(value & 255);
+ }
+
public static unsafe void EncodeUInt32(uint value, byte[] buffer, int offset)
{
fixed (byte* bufferPtr = buffer)
View
5 Enyim.Caching/Memcached/Protocol/Binary/BinaryNode.cs
@@ -27,10 +27,9 @@ public BinaryNode(IPEndPoint endpoint, ISocketPoolConfiguration config, ISaslAut
/// <summary>
/// Creates a new socket then authenticates it before putting it into the pool.
/// </summary>
- /// <returns></returns>
- protected internal override PooledSocket CreateSocket()
+ protected internal override PooledSocket CreateSocket(IPEndPoint endpoint, TimeSpan connectionTimeout, TimeSpan receiveTimeout)
{
- var retval = base.CreateSocket();
+ var retval = base.CreateSocket(endpoint, connectionTimeout, receiveTimeout);
if (this.authenticationProvider != null && !this.Auth(retval))
{
View
4 Enyim.Caching/Memcached/Protocol/Binary/BinaryResponse.cs
@@ -83,9 +83,9 @@ public unsafe bool Read(PooledSocket socket)
this.DataType = buffer[HEADER_DATATYPE];
this.Opcode = buffer[HEADER_OPCODE];
- this.StatusCode = BinaryConverter.DecodeInt16(buffer, HEADER_STATUS);
+ this.StatusCode = BinaryConverter.DecodeUInt16(buffer, HEADER_STATUS);
- this.KeyLength = BinaryConverter.DecodeInt16(buffer, HEADER_KEY);
+ this.KeyLength = BinaryConverter.DecodeUInt16(buffer, HEADER_KEY);
this.CorrelationId = BinaryConverter.DecodeInt32(buffer, HEADER_OPAQUE);
this.CAS = BinaryConverter.DecodeUInt64(buffer, HEADER_CAS);
}
View
10 Enyim.Caching/Memcached/Protocol/Binary/BinarySingleItemOperation.cs
@@ -25,6 +25,16 @@ protected internal override bool ReadResponse(PooledSocket socket)
return retval & this.ProcessResponse(response);
}
+
+ //protected internal override IAsyncResult BeginReadResponse(PooledSocket socket)
+ //{
+ // throw new NotImplementedException();
+ //}
+
+ //protected internal override bool EndReadResponse(IAsyncResult result)
+ //{
+ // throw new NotImplementedException();
+ //}
}
}
View
13 Enyim.Caching/Memcached/Protocol/Operation.cs
@@ -15,6 +15,9 @@ public abstract class Operation : IOperation
internal protected abstract IList<ArraySegment<byte>> GetBuffer();
internal protected abstract bool ReadResponse(PooledSocket socket);
+ //internal protected abstract IAsyncResult BeginReadResponse(PooledSocket socket);
+ //internal protected abstract bool EndReadResponse(IAsyncResult result);
+
IList<ArraySegment<byte>> IOperation.GetBuffer()
{
return this.GetBuffer();
@@ -24,6 +27,16 @@ bool IOperation.ReadResponse(PooledSocket socket)
{
return this.ReadResponse(socket);
}
+
+ //IAsyncResult IOperation.BeginReadResponse(PooledSocket socket)
+ //{
+ // return this.BeginReadResponse(socket);
+ //}
+
+ //bool IOperation.EndReadResponse(IAsyncResult result)
+ //{
+ // return this.EndReadResponse(result);
+ //}
}
}
View
6 Membase/BasicMembaseOperationFactory.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
namespace Membase
{
@@ -15,6 +16,11 @@ IGetAndTouchOperation IMembaseOperationFactory.GetAndTouch(string key, uint newE
{
return new GetAndTouchOperation(null, key, newExpiration);
}
+
+ ISyncOperation IMembaseOperationFactory.Sync(SyncMode mode, KeyValuePair<string, ulong>[] keys, int replicationCount)
+ {
+ throw new NotSupportedException("Sync is not supported on memcached buckets.");
+ }
}
}
View
1  Membase/Configuration/IMembaseClientConfiguration.cs
@@ -57,6 +57,7 @@ public interface IMembaseClientConfiguration
/// <summary>
/// Determines which port the client should use to connect to the nodes
/// </summary>
+ [Obsolete]
BucketPortType Port { get; }
TimeSpan RetryTimeout { get; }
View
2  Membase/Configuration/MembaseClientConfiguration.cs
@@ -97,6 +97,7 @@ public ITranscoder Transcoder
/// <summary>
/// Determines which port the client should use to connect to the nodes
/// </summary>
+ [Obsolete]
public BucketPortType Port { get; set; }
public int RetryCount { get; set; }
@@ -144,6 +145,7 @@ string IMembaseClientConfiguration.Bucket
get { return this.Bucket; }
}
+ [Obsolete]
BucketPortType IMembaseClientConfiguration.Port
{
get { return this.Port; }
View
1  Membase/Configuration/MembaseClientSection.cs
@@ -140,6 +140,7 @@ string IMembaseClientConfiguration.BucketPassword
get { return this.Servers.BucketPassword; }
}
+ [Obsolete]
BucketPortType IMembaseClientConfiguration.Port
{
get { return this.Servers.Port; }
View
1  Membase/Configuration/ServersElement.cs
@@ -74,6 +74,7 @@ public UriElementCollection Urls
/// Determines which port the client should use to connect to the nodes
/// </summary>
[ConfigurationProperty("port", IsRequired = false, DefaultValue = BucketPortType.Direct)]
+ [Obsolete]
public BucketPortType Port
{
get { return (BucketPortType)base["port"]; }
View
1  Membase/IMembaseOperationFactory.cs
@@ -10,5 +10,6 @@ public interface IMembaseOperationFactory : IOperationFactory
{
ITouchOperation Touch(string key, uint newExpiration);
IGetAndTouchOperation GetAndTouch(string key, uint newExpiration);
+ ISyncOperation Sync(SyncMode mode, KeyValuePair<string, ulong>[] keys, int replicationCount);
}
}
View
1  Membase/Membase.csproj
@@ -63,6 +63,7 @@
<Compile Include="MessageStreamListener.cs" />
<Compile Include="MembaseClient.cs" />
<Compile Include="MembasePool.cs" />
+ <Compile Include="Operations\SyncOperation.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Operations\TouchOperation.cs" />
<Compile Include="VBucketAwareOperationFactory.cs" />
View
35 Membase/MembaseClient.cs
@@ -4,6 +4,7 @@
using Enyim.Caching;
using Enyim.Caching.Memcached;
using Membase.Configuration;
+using System.Collections.Generic;
namespace Membase
{
@@ -21,7 +22,7 @@ public class MembaseClient : MemcachedClient
/// Initializes a new instance of the <see cref="T:Membase.MembaseClient" /> class using the default configuration and bucket.
/// </summary>
/// <remarks>The configuration is taken from the /configuration/membase section.</remarks>
- public MembaseClient() : this(DefaultConfig, null, null) { }
+ public MembaseClient() : this(DefaultConfig) { }
/// <summary>
/// Initializes a new instance of the <see cref="T:Membase.MembaseClient" /> class using the default configuration and the specified bucket.
@@ -323,6 +324,38 @@ protected bool PerformTryGetAndTouch(string key, uint nextExpiration, out ulong
return false;
}
+
+ public SyncResult Sync(string key, ulong cas, SyncMode mode)
+ {
+ return this.Sync(key, cas, mode, 0);
+ }
+
+ public SyncResult Sync(string key, ulong cas, SyncMode mode, int replicationCount)
+ {
+ var hashedKey = this.KeyTransformer.Transform(key);
+ var node = this.Pool.Locate(hashedKey);
+
+ if (node != null)
+ using (var ps = node.CreateSocket(TimeSpan.MaxValue, TimeSpan.MaxValue))
+ {
+ var command = this.poolInstance.OperationFactory.Sync(mode, new[] { new KeyValuePair<string, ulong>(hashedKey, cas) }, replicationCount);
+
+ if (node.Execute(ps, command))
+ {
+ var tmp = command.Result;
+ if (tmp.Length == 1)
+ {
+ var retval = tmp[0];
+ retval.Key = key;
+
+ return retval;
+ }
+ }
+ }
+
+ // TODO maybe throw an exception?
+ return null;
+ }
}
}
View
7 Membase/MembasePool.cs
@@ -220,15 +220,12 @@ private InternalState InitBasic(ClusterConfig config, ISaslAuthenticationProvide
if (log.IsInfoEnabled) log.Info("No vbucket. Server count: " + (config.nodes == null ? 0 : config.nodes.Length));
// no vbucket config, use the node list and the ports
- var portType = this.configuration.Port;
+ //var portType = this.configuration.Port;
var tmp = config == null
? Enumerable.Empty<IMemcachedNode>()
: (from node in config.nodes
- let ip = new IPEndPoint(IPAddress.Parse(node.hostname),
- (portType == BucketPortType.Proxy
- ? node.ports.proxy
- : node.ports.direct))
+ let ip = new IPEndPoint(IPAddress.Parse(node.hostname), node.ports.direct)
where node.status == "healthy"
select (IMemcachedNode)(new BinaryNode(ip, this.configuration.SocketPool, auth)));
View
212 Membase/Operations/SyncOperation.cs
@@ -0,0 +1,212 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Enyim.Caching.Memcached.Protocol.Binary;
+using Enyim.Caching.Memcached;
+using System.IO;
+using System.Threading;
+using Enyim.Caching;
+
+namespace Membase
+{
+ [Flags]
+ public enum SyncMode { Mutation = 1, Persistence = 2, Replication = 4 };
+
+ internal class SyncOperation : BinaryOperation, ISyncOperation
+ {
+ private VBucketNodeLocator locator;
+ private KeyValuePair<string, ulong>[] keys;
+ private uint flags;
+
+ public SyncOperation(VBucketNodeLocator locator, KeyValuePair<string, ulong>[] keys, SyncMode mode, int replicationCount)
+ {
+ if (keys == null) throw new ArgumentNullException("keys");
+ if (keys.Length > 0xffff) throw new ArgumentException("Only 0xffff items are supported");
+
+ this.flags = GetFlags(mode, replicationCount);
+
+ this.locator = locator;
+ this.keys = keys;
+ }
+
+ public SyncResult[] Result { get; private set; }
+
+ private static uint GetFlags(SyncMode mode, int replicationCount)
+ {
+ #region [ Flag definitions ]
+ /*
+ Size Field
+ 4 rep count
+ 1 persist flag
+ 1 Mutation flag
+ 1 and/or for rep+persist
+ Replication count: 4 bits. Block until has sent this many replicas (16 replicas ought to be enough for anybody).
+
+ Persistence count: 1 bit. If 1, block until persisted.
+ Mutation flag: If 1, block while the key’s CAS is valid.
+ And/Or flag: If 0 and a replica count and persistence flag are both given, block until either condition is satisfied,
+ else block until both conditions are satisfied.
+
+ Flags layout (32-bit)
+ 16 8 4 1 1 1 1
+ RESERVED RESERVED R P M R+P RESERVED
+ R = Replication count
+ P = Persistence count
+ M = Observe mutation events
+ R+P = replica + persistence operation
+ */
+ #endregion
+
+ if (replicationCount > 16 || replicationCount < 0) throw new ArgumentOutOfRangeException("replicationCount", "<= 0 replicationCount <= 16!");
+
+ uint retval = (uint)(replicationCount << 4);
+
+ var hasRepl = (mode & SyncMode.Replication) == SyncMode.Replication && replicationCount > 0;
+ var hasPers = (mode & SyncMode.Persistence) == SyncMode.Persistence;
+ var hasMut = (mode & SyncMode.Mutation) == SyncMode.Mutation;
+
+ if (hasMut) retval |= 4;
+ if (hasPers) retval |= 8;
+ if (hasRepl && hasPers) retval |= 2;
+
+ return retval;
+ }
+
+ protected override BinaryRequest Build()
+ {
+ var request = new BinaryRequest(0x96)
+ {
+ Data = this.BuildBody()
+ };
+
+ return request;
+ }
+
+ protected unsafe ArraySegment<byte> BuildBody()
+ {
+ var header = new byte[6];
+
+ // 0-3 flags
+ // 4-5 item count
+ BinaryConverter.EncodeUInt32(this.flags, header, 0);
+ BinaryConverter.EncodeUInt16((ushort)this.keys.Length, header, 4);
+
+ var ms = new MemoryStream();
+ ms.Write(header, 0, header.Length);
+
+ var itemHeader = new byte[8 + 2 + 2];
+
+ fixed (byte* p = itemHeader)
+ {
+ // 0- 7: cas
+ // 8- 9: vbucket
+ // 10-11: key length \ repeat
+ // 12- N: key /
+
+ for (var i = 0; i < this.keys.Length; i++)
+ {
+ var keySpec = this.keys[i];
+ var itemKey = Encoding.UTF8.GetBytes(keySpec.Key);
+
+ // cas
+ BinaryConverter.EncodeUInt64(keySpec.Value, p, 0);
+ // vbucket
+ BinaryConverter.EncodeUInt16((ushort)this.locator.GetIndex(keySpec.Key), p, 8);
+ // key length
+ BinaryConverter.EncodeUInt16((ushort)itemKey.Length, p, 10);
+
+ ms.Write(itemHeader, 0, 12);
+ ms.Write(itemKey, 0, itemKey.Length);
+ }
+ }
+
+ return new ArraySegment<byte>(ms.GetBuffer(), 0, (int)ms.Length);
+ }
+
+ protected override bool ReadResponse(PooledSocket socket)
+ {
+ var response = new BinaryResponse();
+ if (response.Read(socket))
+ {
+ this.Result = DecodeResult(response.Data);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private unsafe SyncResult[] DecodeResult(ArraySegment<byte> result)
+ {
+ var data = result.Array;
+
+ fixed (byte* p = data)
+ {
+ var offset = result.Offset;
+ var count = BinaryConverter.DecodeUInt16(p, offset);
+ var retval = new SyncResult[count];
+ offset += 2;
+
+ for (var i = 0; i < retval.Length; i++)
+ {
+ var cas = BinaryConverter.DecodeUInt64(p, offset);
+ // skip vbucket (8-9)
+ var keyLength = BinaryConverter.DecodeUInt16(p, offset + 10);
+ var eventId = (SyncEvent)p[offset + 12];
+ var key = Encoding.UTF8.GetString(data, offset + 13, keyLength);
+
+ retval[i] = new SyncResult
+ {
+ Cas = cas,
+ Event = eventId,
+ Key = key
+ };
+
+ offset += (13 + keyLength);
+ }
+
+ return retval;
+ }
+ }
+
+ SyncResult[] ISyncOperation.Result
+ {
+ get { return this.Result; }
+ }
+ }
+
+ public class SyncResult
+ {
+ public string Key { get; internal set; }
+ public ulong Cas { get; internal set; }
+ public SyncEvent Event { get; internal set; }
+ }
+
+ public enum SyncEvent { Unknown = 0, Persisted, Modified, Replicated, Deleted, InvalidKey, InvalidCas }
+
+ public interface ISyncOperation : IOperation
+ {
+ SyncResult[] Result { get; }
+ }
+}
+
+#region [ License information ]
+/* ************************************************************
+ *
+ * Copyright (c) 2010 Attila Kiskó, enyim.com
+ *
+ * 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.
+ *
+ * ************************************************************/
+#endregion
View
5 Membase/VBucketAwareOperationFactory.cs
@@ -323,6 +323,11 @@ OperationState IOperationWithState.State
}
#endregion
+
+ ISyncOperation IMembaseOperationFactory.Sync(SyncMode mode, KeyValuePair<string, ulong>[] keys, int replicationCount)
+ {
+ return new SyncOperation(this.locator, keys, mode, replicationCount);
+ }
}
internal interface IOperationWithState
View
21 MemcachedTest/KetamaTest.cs
@@ -3321,20 +3321,15 @@ bool IMemcachedNode.Execute(IOperation op)
return true;
}
- //IAsyncResult IMemcachedNode.BeginExecute(IOperation op, AsyncCallback callback, object state)
- //{
- // throw new NotImplementedException();
- //}
-
- //bool IMemcachedNode.EndExecute(IAsyncResult result)
- //{
- // throw new NotImplementedException();
- //}
-
- #endregion
-
- #region IMemcachedNode Members
+ bool IMemcachedNode.Execute(PooledSocket socket, IOperation op)
+ {
+ return true;
+ }
+ PooledSocket IMemcachedNode.CreateSocket(TimeSpan connectionTimeout, TimeSpan receiveTimeout)
+ {
+ throw new NotImplementedException();
+ }
event Action<IMemcachedNode> IMemcachedNode.Failed
{
View
10 MemcachedTest/MemcachedTest.csproj
@@ -23,8 +23,14 @@
<Reference Include="log4net">
<HintPath>..\binaries\log4net\log4net.dll</HintPath>
</Reference>
- <Reference Include="nunit.framework, Version=2.5.7.10213, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
- <Reference Include="nunit.mocks, Version=2.5.7.10213, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
+ <Reference Include="nunit.framework, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\binaries\nunit\framework\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="nunit.mocks, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\binaries\nunit\framework\nunit.mocks.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Core">
View
BIN  binaries/nunit/framework/nunit.framework.dll
Binary file not shown
View
10,407 binaries/nunit/framework/nunit.framework.xml
10,407 additions, 0 deletions not shown
View
BIN  binaries/nunit/framework/nunit.mocks.dll
Binary file not shown
View
2  build/VersionInfo.targets
@@ -37,7 +37,7 @@
<AssemblyOriginatorKeyFile></AssemblyOriginatorKeyFile>
</PropertyGroup>
- <Target Name="CreateAssemblyInfoFromGit" DependsOnTargets="CreateRandomFileNames" Condition="$(ShouldGenerate) == 'true'">
+ <Target Name="CreateAssemblyInfoFromGit" Condition="$(ShouldGenerate) == 'true'">
<MakeDir Directories="obj\$(Configuration)" ContinueOnError="true" />
<Exec Command="git describe --tags --match $(GitTagMatch) > $(GitDescribe)" />
<ReadLinesFromFile File="$(GitDescribe)">

No commit comments for this range

Something went wrong with that request. Please try again.