コード例 #1
0
        private static DynamicMethod BuildDispatchingMethod(IActor handler, IStructSizeCounter counter,
                                                            Func <Type, int> messageIdGetter)
        {
            var handlerType   = handler.GetType();
            var handleMethods = ActorRegistry.GetHandleMethods(handlerType)
                                .ToDictionary(m => messageIdGetter(m.GetParameters()[1].ParameterType.GetElementType()), m => m)
                                .OrderBy(kvp => kvp.Key)
                                .ToArray();

            var dm = new DynamicMethod("ReadMessagesFor_" + handlerType.Namespace.Replace(".", "_") + handlerType.Name,
                                       typeof(void), new[] { typeof(MessageReader), typeof(int), typeof(ByteChunk) },
                                       handlerType.Assembly.Modules.First(), true);

            var actorField = typeof(MessageReader).GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                             .Single(fi => fi.FieldType == typeof(IActor));

            var il = dm.GetILGenerator();

            // push handler
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, actorField);
            il.Emit(OpCodes.Castclass, handlerType);

            var endLbl = il.DefineLabel();

            // dispatch
            foreach (var method in handleMethods)
            {
                var lbl = il.DefineLabel();
                il.Emit(OpCodes.Ldarg_1); // messageTypeId
                il.Emit(OpCodes.Ldc_I4, method.Key);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Brfalse_S, lbl);

                // push envelope
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Ldfld, typeof(ByteChunk).GetField("Pointer"));

                //var messageType = method.Value.GetParameters()[1].ParameterType.GetElementType();
                //il.Emit(OpCodes.Ldc_I4, (int)Marshal.OffsetOf(messageType, Envelope.FieldName));
                //il.Emit(OpCodes.Add);

                // push message
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Ldfld, typeof(ByteChunk).GetField("Pointer"));

                il.EmitCall(OpCodes.Callvirt, method.Value, null);
                il.Emit(OpCodes.Br_S, endLbl);
                il.MarkLabel(lbl);
            }

            // nothing was called, pop
            il.Emit(OpCodes.Pop);

            // end label
            il.MarkLabel(endLbl);
            il.Emit(OpCodes.Ret);
            return(dm);
        }
コード例 #2
0
ファイル: MessageReader.cs プロジェクト: Scooletz/RampUp
        private static DynamicMethod BuildDispatchingMethod(IActor handler, IStructSizeCounter counter,
            Func<Type, int> messageIdGetter)
        {
            var handlerType = handler.GetType();
            var handleMethods = ActorRegistry.GetHandleMethods(handlerType)
                .ToDictionary(m => messageIdGetter(m.GetParameters()[1].ParameterType.GetElementType()), m => m)
                .OrderBy(kvp => kvp.Key)
                .ToArray();

            var dm = new DynamicMethod("ReadMessagesFor_" + handlerType.Namespace.Replace(".", "_") + handlerType.Name,
                typeof (void), new[] {typeof (MessageReader), typeof (int), typeof (ByteChunk)},
                handlerType.Assembly.Modules.First(), true);

            var actorField = typeof (MessageReader).GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                .Single(fi => fi.FieldType == typeof (IActor));

            var il = dm.GetILGenerator();

            // push handler
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, actorField);
            il.Emit(OpCodes.Castclass, handlerType);

            var endLbl = il.DefineLabel();

            // dispatch
            foreach (var method in handleMethods)
            {
                var lbl = il.DefineLabel();
                il.Emit(OpCodes.Ldarg_1); // messageTypeId
                il.Emit(OpCodes.Ldc_I4, method.Key);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Brfalse_S, lbl);

                // push envelope
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Ldfld, typeof (ByteChunk).GetField("Pointer"));

                //var messageType = method.Value.GetParameters()[1].ParameterType.GetElementType();
                //il.Emit(OpCodes.Ldc_I4, (int)Marshal.OffsetOf(messageType, Envelope.FieldName));
                //il.Emit(OpCodes.Add);

                // push message
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Ldfld, typeof (ByteChunk).GetField("Pointer"));

                il.EmitCall(OpCodes.Callvirt, method.Value, null);
                il.Emit(OpCodes.Br_S, endLbl);
                il.MarkLabel(lbl);
            }

            // nothing was called, pop
            il.Emit(OpCodes.Pop);

            // end label
            il.MarkLabel(endLbl);
            il.Emit(OpCodes.Ret);
            return dm;
        }
コード例 #3
0
ファイル: MessageReader.cs プロジェクト: Scooletz/RampUp
        public MessageReader(IActor handler, IStructSizeCounter counter, Func<Type, int> messageIdGetter)
        {
            _handler = handler;
            var dm = BuildDispatchingMethod(handler, counter, messageIdGetter);

            _reader =
                (Action<MessageReader, int, ByteChunk>)
                    dm.CreateDelegate(typeof (Action<MessageReader, int, ByteChunk>));
        }
コード例 #4
0
        public MessageReader(IActor handler, IStructSizeCounter counter, Func <Type, int> messageIdGetter)
        {
            _handler = handler;
            var dm = BuildDispatchingMethod(handler, counter, messageIdGetter);

            _reader =
                (Action <MessageReader, int, ByteChunk>)
                dm.CreateDelegate(typeof(Action <MessageReader, int, ByteChunk>));
        }
コード例 #5
0
ファイル: MessageMetadata.cs プロジェクト: Scooletz/RampUp
        public static LongLookup<MessageMetadata> BuildMetadata(IStructSizeCounter counter,
            Func<Type, int> messageIdGetter, Type[] structTypes)
        {
            var keys = structTypes.Select(GetKey).ToArray();

            var values =
                structTypes.Select(type => new MessageMetadata(messageIdGetter(type), (short) counter.GetSize(type),
                    (short) (int) Marshal.OffsetOf(type, Envelope.FieldName))).ToArray();

            var metadata = new LongLookup<MessageMetadata>(keys, values);
            return metadata;
        }
コード例 #6
0
        public static LongLookup <MessageMetadata> BuildMetadata(IStructSizeCounter counter,
                                                                 Func <Type, int> messageIdGetter, Type[] structTypes)
        {
            var keys = structTypes.Select(GetKey).ToArray();

            var values =
                structTypes.Select(type => new MessageMetadata(messageIdGetter(type), (short)counter.GetSize(type),
                                                               (short)(int)Marshal.OffsetOf(type, Envelope.FieldName))).ToArray();

            var metadata = new LongLookup <MessageMetadata>(keys, values);

            return(metadata);
        }
コード例 #7
0
ファイル: CompositeActor.cs プロジェクト: zhangz/RampUp
        public CompositeActor(IActor[] actors, IStructSizeCounter counter, Func <Type, int> messageIdGetter)
        {
            if (actors.Length > MaxActors)
            {
                throw new ArgumentException($"Too many actors. Can composite only up to {MaxActors}");
            }

            var messageTypes = actors.Select(a => new ActorDescriptor(a))
                               .SelectMany(descriptor => descriptor.HandledMessageTypes)
                               .Distinct()
                               .ToArray();

            Descriptor = new ActorDescriptor(messageTypes);
            _readers   = actors.Select(a => new MessageReader(a, counter, messageIdGetter)).ToArray();
            _count     = _readers.Length;

            _messageMap = BuildMessageMap(actors, messageIdGetter);
            _batchAware = actors.OfType <IBatchAware>().ToArray();
        }
コード例 #8
0
ファイル: CompositeActor.cs プロジェクト: Scooletz/RampUp
        public CompositeActor(IActor[] actors, IStructSizeCounter counter, Func<Type, int> messageIdGetter)
        {
            if (actors.Length > MaxActors)
            {
                throw new ArgumentException($"Too many actors. Can composite only up to {MaxActors}");
            }

            var messageTypes = actors.Select(a => new ActorDescriptor(a))
                .SelectMany(descriptor => descriptor.HandledMessageTypes)
                .Distinct()
                .ToArray();

            Descriptor = new ActorDescriptor(messageTypes);
            _readers = actors.Select(a => new MessageReader(a, counter, messageIdGetter)).ToArray();
            _count = _readers.Length;

            _messageMap = BuildMessageMap(actors, messageIdGetter);
            _batchAware = actors.OfType<IBatchAware>().ToArray();
        }
コード例 #9
0
 public Runner(IRingBuffer buffer, IStructSizeCounter counter, Func <Type, int> messageIdGetter, int batchSize,
               params IActor[] actors)
 {
     Buffer     = buffer;
     _batchSize = batchSize;
     if (actors.Length > 1)
     {
         var actor = new CompositeActor(actors, counter, messageIdGetter);
         _batchAware = actor;
         _handler    = actor.MessageHandler;
         Descriptor  = actor.Descriptor;
     }
     else
     {
         _handler    = new MessageReader(actors[0], counter, messageIdGetter).MessageHandlerImpl;
         Descriptor  = new ActorDescriptor(actors[0]);
         _batchAware = actors[0] as IBatchAware;
     }
 }
コード例 #10
0
ファイル: Runner.cs プロジェクト: Scooletz/RampUp
 public Runner(IRingBuffer buffer, IStructSizeCounter counter, Func<Type, int> messageIdGetter, int batchSize,
     params IActor[] actors)
 {
     Buffer = buffer;
     _batchSize = batchSize;
     if (actors.Length > 1)
     {
         var actor = new CompositeActor(actors, counter, messageIdGetter);
         _batchAware = actor;
         _handler = actor.MessageHandler;
         Descriptor = actor.Descriptor;
     }
     else
     {
         _handler = new MessageReader(actors[0], counter, messageIdGetter).MessageHandlerImpl;
         Descriptor = new ActorDescriptor(actors[0]);
         _batchAware = actors[0] as IBatchAware;
     }
 }
コード例 #11
0
        public static IMessageWriter Build(IStructSizeCounter counter, Func <Type, int> messageIdGetter,
                                           Type[] structTypes, ModuleBuilder module)
        {
            const string metadataFieldName = "metadata";
            var          writer            = module.DefineType("MessageWriter", typeof(SomeWriter).Attributes, typeof(object));

            writer.PadBefore();
            var metadataField = writer.DefineField(metadataFieldName, LookupType, FieldAttributes.Public);

            writer.PadAfter();
            writer.AddInterfaceImplementation(typeof(IMessageWriter));

            BuildWriteMethod(writer, metadataField);

            // initialize
            var metadata = MessageMetadata.BuildMetadata(counter, messageIdGetter, structTypes);

            var instance = Activator.CreateInstance(writer.CreateType());

            instance.GetType().GetField(metadataFieldName).SetValue(instance, metadata);
            return((IMessageWriter)instance);
        }