using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Microsoft.Research.Science.Data.NetCDF4 { internal static class ChunkSizeSelector { public const int suggestedChunkPower = 13; // 8 Kb public const int maxAllowedChunkPower = 17; // 128 Kb public static int GetChunkSize(Type type, int rank) { int sizeBytes = GetSizeOfType(type); int s = Log2m((uint)sizeBytes); for (int n = suggestedChunkPower; n <= maxAllowedChunkPower; n++) { if (n <= s) continue; int p = (n - s) / rank; if (p * rank == n - s) return Pow(p); } for (int n = suggestedChunkPower - 1; n > s; n--) { int p = (n - s) / rank; if (p * rank == n - s) return Pow(p); } return 1; } static int Pow(int p) { return 1 << p; } static int Log2m(uint n) { if (n < 0) throw new ArgumentException("n must be positive"); if (n == 1) return 0; int log = 32; // max while ((n & 0x80000000) == 0) { n <<= 1; log--; } if ((n ^ 0x80000000) == 0) log--; return log; } private static int GetSizeOfType(Type type) { if (type == typeof(Double)) return sizeof(Double); else if (type == typeof(Single)) return sizeof(Single); else if (type == typeof(Int16)) return sizeof(Int16); else if (type == typeof(Int32)) return sizeof(Int32); else if (type == typeof(Int64)) return sizeof(Int64); else if (type == typeof(UInt64)) return sizeof(UInt64); else if (type == typeof(UInt32)) return sizeof(UInt32); else if (type == typeof(UInt16)) return sizeof(UInt16); else if (type == typeof(Byte)) return sizeof(Byte); else if (type == typeof(SByte)) return sizeof(SByte); else if (type == typeof(String)) return 32; else if (type == typeof(DateTime)) return sizeof(double); else if (type == typeof(Boolean)) return sizeof(byte); return 1; } } }