private static void DivideNode(BoundingRectangle space, INode <T> input, Node <T> output, ArrayPool <float> pool, Treemap <T> map) { //Recursion base case if (input.Count == 0) { return; } var h = pool.Allocate(input.Count); var v = pool.Allocate(input.Count); //Take the split with the least bad aspect ratio if (MeasureSizes(false, space, input, h) < MeasureSizes(true, space, input, v)) { //Free the unused array pool.Free(v); SplitHorizontal(space, input, output, h, pool, map); } else { //Free the unused array pool.Free(h); SplitVertical(space, input, output, v, pool, map); } }
public void AssertThat_AllocatedArray_IsLargeEnough_WhenRecycling() { //Allocate a large enough array var a = _pool.Allocate(10); //Free it _pool.Free(a); //Allocate again, let's see if we get a large enough array Assert.IsTrue(_pool.Allocate(5).Length >= 5); }
public void CookOverride() { SmeltTicks++; if (SmeltTicks % 2 == 0) { TrySmeltItems(); } var burnable = _plugin.FindBurnable(Furnace); if (burnable == null) { _plugin.StopCooking(Furnace); return; } ItemModBurnable component = burnable.info.GetComponent <ItemModBurnable>(); burnable.fuel -= 0.5f * Furnace.cookingTemperature / 200f; if (!burnable.HasFlag(global::Item.Flag.OnFire)) { burnable.SetFlag(global::Item.Flag.OnFire, true); burnable.MarkDirty(); } if (burnable.fuel <= 0f) { var array = ArrayPool.Get(2); array[0] = burnable; array[1] = component; ConsumeFuelMethod.Invoke(Furnace, array); ArrayPool.Free(array); } }
private static void ApplySplit(BoundingRectangle space, INode <T> input, Node <T> output, float[] sizes, ArrayPool <float> pool, Treemap <T> map) { //Create child nodes and add them to the parent var index = 0; foreach (var child in input) { output.Add(new Node <T>(map, child.Value, sizes[index++])); } //Now that we're done with the array, free it pool.Free(sizes); //Recursively subdivide each child for (var i = 0; i < output.Count; i++) { var iNode = input[i]; var oNode = output[i]; //Calculate bounds for this node (the bounds are not in the right place, they are the right *size* which is the only thing we care about here) var box = output.SplitVertical ? new BoundingRectangle(new Vector2(0, space.Min.Y), new Vector2(oNode.Length, space.Max.Y)) : new BoundingRectangle(new Vector2(space.Min.X, 0), new Vector2(space.Max.X, oNode.Length)); //Recursion DivideNode(box, iNode, oNode, pool, map); } }
/// <summary> /// Returns the matrix to the pool /// </summary> /// <param name="matrices"></param> public void Free(params Matrix[] matrices) { foreach (var mtx in matrices) { if (mtx.CoreArray == null) { continue; } Pool.Free(mtx.CoreArray); mtx.CoreArray = null; TotalReturns++; } }
protected List <HookMethod> FindHooks(string name, object[] args) { HookCache hookCache; object[] defaultValue; bool flag; List <HookMethod> hookMethod = this.HooksCache.GetHookMethod(name, args, out hookCache); if (hookMethod != null) { return(hookMethod); } List <HookMethod> hookMethods = new List <HookMethod>(); if (!this.Hooks.TryGetValue(name, out hookMethod)) { return(hookMethods); } HookMethod hookMethod1 = null; HookMethod hookMethod2 = null; foreach (HookMethod hookMethod3 in hookMethod) { if (!hookMethod3.IsBaseHook) { int num = (args != null ? (int)args.Length : 0); bool flag1 = false; if (num == (int)hookMethod3.Parameters.Length) { defaultValue = args; } else { defaultValue = ArrayPool.Get((int)hookMethod3.Parameters.Length); flag1 = true; if (num > 0 && defaultValue.Length != 0) { Array.Copy(args, defaultValue, Math.Min(num, (int)defaultValue.Length)); } if ((int)defaultValue.Length > num) { for (int i = num; i < (int)defaultValue.Length; i++) { ParameterInfo parameters = hookMethod3.Parameters[i]; if (parameters.DefaultValue != null && parameters.DefaultValue != DBNull.Value) { defaultValue[i] = parameters.DefaultValue; } else if (parameters.ParameterType.IsValueType) { defaultValue[i] = Activator.CreateInstance(parameters.ParameterType); } } } } if (hookMethod3.HasMatchingSignature(defaultValue, out flag)) { if (!flag) { hookMethod2 = hookMethod3; } else { hookMethod1 = hookMethod3; if (hookMethod1 != null) { hookMethods.Add(hookMethod1); } else if (hookMethod2 != null) { hookMethods.Add(hookMethod2); } hookCache.SetupMethods(hookMethods); return(hookMethods); } } if (!flag1) { continue; } ArrayPool.Free(defaultValue); } else { hookMethods.Add(hookMethod3); } } if (hookMethod1 != null) { hookMethods.Add(hookMethod1); } else if (hookMethod2 != null) { hookMethods.Add(hookMethod2); } hookCache.SetupMethods(hookMethods); return(hookMethods); }
protected sealed override object OnCallHook(string name, object[] args) { object[] defaultValue; object obj = null; bool flag = false; foreach (HookMethod hookMethod in this.FindHooks(name, args)) { int num = (args != null ? (int)args.Length : 0); if (num == (int)hookMethod.Parameters.Length) { defaultValue = args; } else { defaultValue = ArrayPool.Get((int)hookMethod.Parameters.Length); flag = true; if (num > 0 && defaultValue.Length != 0) { Array.Copy(args, defaultValue, Math.Min(num, (int)defaultValue.Length)); } if ((int)defaultValue.Length > num) { for (int i = num; i < (int)defaultValue.Length; i++) { ParameterInfo parameters = hookMethod.Parameters[i]; if (parameters.DefaultValue != null && parameters.DefaultValue != DBNull.Value) { defaultValue[i] = parameters.DefaultValue; } else if (parameters.ParameterType.IsValueType) { defaultValue[i] = Activator.CreateInstance(parameters.ParameterType); } } } } try { obj = this.InvokeMethod(hookMethod, defaultValue); } catch (TargetInvocationException targetInvocationException1) { TargetInvocationException targetInvocationException = targetInvocationException1; if (flag) { ArrayPool.Free(defaultValue); } Exception innerException = targetInvocationException.InnerException; if (innerException == null) { innerException = targetInvocationException; } throw innerException; } if (num != (int)hookMethod.Parameters.Length) { for (int j = 0; j < (int)hookMethod.Parameters.Length; j++) { if (hookMethod.Parameters[j].IsOut || hookMethod.Parameters[j].ParameterType.IsByRef) { args[j] = defaultValue[j]; } } } if (!flag) { continue; } ArrayPool.Free(defaultValue); } return(obj); }
/// <summary> /// Calls a hook on all plugins of this manager /// </summary> /// <param name="hook"></param> /// <param name="args"></param> /// <returns></returns> public object CallHook(string hook, params object[] args) { // Locate the sublist if (!hookSubscriptions.TryGetValue(hook, out IList <Plugin> plugins)) { return(null); } if (plugins.Count == 0) { return(null); } // Loop each item object[] values = ArrayPool.Get(plugins.Count); int returnCount = 0; object finalValue = null; Plugin finalPlugin = null; for (int i = 0; i < plugins.Count; i++) { // Call the hook object value = plugins[i].CallHook(hook, args); if (value != null) { values[i] = value; finalValue = value; finalPlugin = plugins[i]; returnCount++; } } // Is there a return value? if (returnCount == 0) { ArrayPool.Free(values); return(null); } if (returnCount > 1 && finalValue != null) { // Notify log of hook conflict hookConflicts.Clear(); for (int i = 0; i < plugins.Count; i++) { object value = values[i]; if (value == null) { continue; } if (value.GetType().IsValueType) { if (!values[i].Equals(finalValue)) { hookConflicts.Add($"{plugins[i].Name} - {value} ({value.GetType().Name})"); } } else { if (values[i] != finalValue) { hookConflicts.Add($"{plugins[i].Name} - {value} ({value.GetType().Name})"); } } } if (hookConflicts.Count > 0) { hookConflicts.Add($"{finalPlugin.Name} ({finalValue} ({finalValue.GetType().Name}))"); Logger.Write(LogType.Warning, "Calling hook {0} resulted in a conflict between the following plugins: {1}", hook, string.Join(", ", hookConflicts.ToArray())); } } ArrayPool.Free(values); return(finalValue); }
public object CallHook(string hook, params object[] args) { IList <Plugin> plugins; if (!this.hookSubscriptions.TryGetValue(hook, out plugins)) { return(null); } if (plugins.Count == 0) { return(null); } object[] objArray = ArrayPool.Get(plugins.Count); int num = 0; object obj = null; Plugin item = null; for (int i = 0; i < plugins.Count; i++) { object obj1 = plugins[i].CallHook(hook, args); if (obj1 != null) { objArray[i] = obj1; obj = obj1; item = plugins[i]; num++; } } if (num == 0) { ArrayPool.Free(objArray); return(null); } if (num > 1 && obj != null) { this.hookConflicts.Clear(); for (int j = 0; j < plugins.Count; j++) { object obj2 = objArray[j]; if (obj2 != null) { if (obj2.GetType().IsValueType) { if (!objArray[j].Equals(obj)) { this.hookConflicts.Add(string.Format("{0} - {1} ({2})", plugins[j].Name, obj2, obj2.GetType().Name)); } } else if (objArray[j] != obj) { this.hookConflicts.Add(string.Format("{0} - {1} ({2})", plugins[j].Name, obj2, obj2.GetType().Name)); } } } if (this.hookConflicts.Count > 0) { this.hookConflicts.Add(string.Format("{0} ({1} ({2}))", item.Name, obj, obj.GetType().Name)); this.Logger.Write(LogType.Warning, "Calling hook {0} resulted in a conflict between the following plugins: {1}", new object[] { hook, string.Join(", ", this.hookConflicts.ToArray()) }); } } ArrayPool.Free(objArray); return(obj); }
protected List <HookMethod> FindHooks(string name, object[] args) { // Get the full name of the hook `name(argument type 1, argument type 2, ..., argument type x)` // Check the cache if we already found a match for this hook HookCache cache; List <HookMethod> methods = HooksCache.GetHookMethod(name, args, out cache); if (methods != null) { return(methods); } List <HookMethod> matches = new List <HookMethod>(); // Get all hook methods that could match, return an empty list if none match if (!Hooks.TryGetValue(name, out methods)) { return(matches); } // Find matching hooks HookMethod exactMatch = null; HookMethod overloadedMatch = null; foreach (HookMethod h in methods) { // A base hook should always have a matching signature either directly or through inheritance // and should always be called as core functionality depends on it. if (h.IsBaseHook) { matches.Add(h); continue; } // Check if this method matches the hook arguments passed if it isn't a base hook object[] hookArgs; int received = args?.Length ?? 0; bool pooledArray = false; if (received != h.Parameters.Length) { // The call argument count is different to the declared callback methods argument count hookArgs = ArrayPool.Get(h.Parameters.Length); pooledArray = true; if (received > 0 && hookArgs.Length > 0) { // Remove any additional arguments which the callback method does not declare Array.Copy(args, hookArgs, Math.Min(received, hookArgs.Length)); } if (hookArgs.Length > received) { // Create additional parameters for arguments excluded in this hook call for (int n = received; n < hookArgs.Length; n++) { ParameterInfo parameter = h.Parameters[n]; if (parameter.DefaultValue != null && parameter.DefaultValue != DBNull.Value) { // Use the default value that was provided by the method definition hookArgs[n] = parameter.DefaultValue; } else if (parameter.ParameterType.IsValueType) { // Use the default value for value types hookArgs[n] = Activator.CreateInstance(parameter.ParameterType); } } } } else { hookArgs = args; } bool isExactMatch; if (h.HasMatchingSignature(hookArgs, out isExactMatch)) { if (isExactMatch) { exactMatch = h; break; } // Should we determine the level and call the closest overloaded match? Performance impact? overloadedMatch = h; } if (pooledArray) { ArrayPool.Free(hookArgs); } } if (exactMatch != null) { matches.Add(exactMatch); } else { if (overloadedMatch != null) { matches.Add(overloadedMatch); } } cache.SetupMethods(matches); return(matches); }
/// <summary> /// Calls the specified hook on this plugin /// </summary> /// <param name="name"></param> /// <param name="args"></param> /// <returns></returns> protected sealed override object OnCallHook(string name, object[] args) { object returnvalue = null; bool pooledArray = false; // Call all hooks that match the signature foreach (HookMethod h in FindHooks(name, args)) { int received = args?.Length ?? 0; object[] hookArgs; if (received != h.Parameters.Length) { // The call argument count is different to the declared callback methods argument count hookArgs = ArrayPool.Get(h.Parameters.Length); pooledArray = true; if (received > 0 && hookArgs.Length > 0) { // Remove any additional arguments which the callback method does not declare Array.Copy(args, hookArgs, Math.Min(received, hookArgs.Length)); } if (hookArgs.Length > received) { // Create additional parameters for arguments excluded in this hook call for (int n = received; n < hookArgs.Length; n++) { ParameterInfo parameter = h.Parameters[n]; if (parameter.DefaultValue != null && parameter.DefaultValue != DBNull.Value) { // Use the default value that was provided by the method definition hookArgs[n] = parameter.DefaultValue; } else if (parameter.ParameterType.IsValueType) { // Use the default value for value types hookArgs[n] = Activator.CreateInstance(parameter.ParameterType); } } } } else { hookArgs = args; } try { returnvalue = InvokeMethod(h, hookArgs); } catch (TargetInvocationException ex) { if (pooledArray) { ArrayPool.Free(hookArgs); } throw ex.InnerException ?? ex; } if (received != h.Parameters.Length) { // A copy of the call arguments was used for this method call for (int n = 0; n < h.Parameters.Length; n++) { // Copy output values for out and by reference arguments back to the calling args if (h.Parameters[n].IsOut || h.Parameters[n].ParameterType.IsByRef) { args[n] = hookArgs[n]; } } } if (pooledArray) { ArrayPool.Free(hookArgs); } } return(returnvalue); }
public static void Free <T>(this T[] array) { ArrayPool <T> .Free(array); }
private async Task QueryCore( bool async, string queryText, PostgresCommand command, CancellationToken cancellationToken) { BindParameter[] parameters = null; var parameterCount = command.Parameters.Count; try { if (parameterCount > 0) { parameters = ArrayPool <BindParameter> .GetArray(parameterCount); var encoding = ClientState.ClientEncoding; for (var i = 0; i < parameterCount; ++i) { var param = command.Parameters[i].Value; if (param == null) { parameters[i] = new BindParameter { ParameterByteCount = 0, Parameters = EmptyArray <byte> .Value }; continue; } // TODO: This allocation fest is terrible. Make this // write directly to the memorystream instead of having // intermittent buffers for everything. var paramString = param.ToString(); var maxBytes = encoding .GetMaxByteCount(paramString.Length); var paramBuffer = ArrayPool <byte> .GetArray(maxBytes); var actualBytes = encoding.GetBytes( paramString, 0, paramString.Length, paramBuffer, 0); parameters[i] = new BindParameter { ParameterByteCount = actualBytes, Parameters = paramBuffer }; } } WriteMessage(new ParseMessage { Query = queryText }); WriteMessage(new BindMessage { PreparedStatementName = "", ResultColumnFormatCodeCount = 1, ParameterCount = (short)parameterCount, Parameters = parameters, ResultColumnFormatCodes = QueryResultFormat == PostgresFormatCode.Binary ? _binaryFormatCode : _textFormatCode }); WriteMessage(new DescribeMessage { StatementTargetType = StatementTargetType.Portal }); WriteMessage(new ExecuteMessage { }); WriteMessage(new SyncMessage { }); await FlushWrites(async, cancellationToken) .ConfigureAwait(false); } finally { if (parameters != null) { for (var i = 0; i < parameterCount; ++i) { var param = parameters[i].Parameters; ArrayPool.Free(ref param); } } } }
private async Task OpenAsync(bool async, CancellationToken cancellationToken) { ResetBuffer(); _state = ConnectionState.Connecting; await CreateConnection(cancellationToken) .ConfigureAwait(false); const int messageCount = 3; var messages = ArrayPool <KeyValuePair <string, string> > .GetArray(messageCount); try { messages[0] = new KeyValuePair <string, string>( "user", PostgresConnectionString.Username); messages[1] = new KeyValuePair <string, string>( "client_encoding", PostgresConnectionString.Encoding); messages[2] = new KeyValuePair <string, string>( "database", PostgresConnectionString.Database); WriteMessage(new StartupMessage { MessageCount = messageCount, Messages = messages }); } finally { ArrayPool.Free(ref messages); } await FlushWrites(async, cancellationToken) .ConfigureAwait(false); var authMessageTask = EnsureNextMessage <AuthenticationMessage>( async, cancellationToken); using (var authMessage = await authMessageTask .ConfigureAwait(false)) { Authenticate(authMessage); } await FlushWrites(async, cancellationToken) .ConfigureAwait(false); var authMessageOkTask = EnsureNextMessage <AuthenticationMessage>( async, cancellationToken); using (var authOkMessage = await authMessageOkTask .ConfigureAwait(false)) { authOkMessage.AsssertIsOk(); } var foundIdleMessage = false; do { var message = await ReadNextMessage(async, cancellationToken) .ConfigureAwait(false); switch (message) { case BackendKeyDataMessage keyDataMessage: // TODO: Throw not supported exception? break; case ReadyForQueryMessage readyMessage: _state = ConnectionState.Open; readyMessage.AssertType(TransactionIndicatorType.Idle); foundIdleMessage = true; break; default: throw new PostgresInvalidMessageException(message); } } while (!foundIdleMessage); }