Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but 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
Attila Kiskó 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
Attila Kiskó Single item implementation of the Sync command. 7cf27fb
Attila Kiskó Fix release build. 4563354
Attila Kiskó 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
Attila Kiskó Totally kill the hash algo caching, something strange is happening wi…
…th HttpContext.Items
931f31e
Attila Kiskó Ignore the proxy port everywhere. 896f585
Commits on May 17, 2011
Farshid Ghods 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
2  Enyim.Caching/Memcached/IMemcachedNode.cs
View
@@ -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;
24 Enyim.Caching/Memcached/Locators/KetamaNodeLocator.cs
View
@@ -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
}
}
57 Enyim.Caching/Memcached/MemcachedNode.cs
View
@@ -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
}
}
8 Enyim.Caching/Memcached/PooledSocket.cs
View
@@ -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 =>
{
20 Enyim.Caching/Memcached/Protocol/Binary/BinaryConverter.cs
View
@@ -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)
5 Enyim.Caching/Memcached/Protocol/Binary/BinaryNode.cs
View
@@ -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))
{
4 Enyim.Caching/Memcached/Protocol/Binary/BinaryResponse.cs
View
@@ -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);
}
10 Enyim.Caching/Memcached/Protocol/Binary/BinarySingleItemOperation.cs
View
@@ -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();
+ //}
}
}
13 Enyim.Caching/Memcached/Protocol/Operation.cs
View
@@ -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);
+ //}
}
}
6 Membase/BasicMembaseOperationFactory.cs
View
@@ -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.");
+ }
}
}
1  Membase/Configuration/IMembaseClientConfiguration.cs
View
@@ -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; }
2  Membase/Configuration/MembaseClientConfiguration.cs
View
@@ -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; }
1  Membase/Configuration/MembaseClientSection.cs
View
@@ -140,6 +140,7 @@ string IMembaseClientConfiguration.BucketPassword
get { return this.Servers.BucketPassword; }
}
+ [Obsolete]
BucketPortType IMembaseClientConfiguration.Port
{
get { return this.Servers.Port; }
1  Membase/Configuration/ServersElement.cs
View
@@ -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"]; }
1  Membase/IMembaseOperationFactory.cs
View
@@ -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);
}
}
1  Membase/Membase.csproj
View
@@ -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" />
35 Membase/MembaseClient.cs
View
@@ -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;
+ }
}
}
7 Membase/MembasePool.cs
View
@@ -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)));
212 Membase/Operations/SyncOperation.cs
View
@@ -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
5 Membase/VBucketAwareOperationFactory.cs
View
@@ -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
21 MemcachedTest/KetamaTest.cs
View
@@ -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
{
10 MemcachedTest/MemcachedTest.csproj
View
@@ -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">
BIN  binaries/nunit/framework/nunit.framework.dll
View
Binary file not shown
10,407 binaries/nunit/framework/nunit.framework.xml
View
10,407 additions, 0 deletions not shown
BIN  binaries/nunit/framework/nunit.mocks.dll
View
Binary file not shown
2  build/VersionInfo.targets
View
@@ -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.