Write a class called ByteArray that implement allocating, reading and writing to an array of bytes. The runtime environment has a limitation. The maximum continuous memory size that it can allocated is 64k bytes. It can allocate many 64K ( or less) chunks.
The ByteArray class should hide this limitation and support allocating arrays larger than 64K as in the following example :
ByteArray ba = new ByteArray (250000); // Create
ba[150000] = 15; // Write byte
byte x = ba[190000]; // Read byte
This question is really asking for if you know how to implement the index. I responded with the following one minute recipe.
class ByteArray { byte[] _Byte; const int _MaxSizeinKB = 64; const int _MaxSizeInBytes = _MaxSizeinKB * 1024; public ByteArray(int nLength) { if (nLength > _MaxSizeInBytes) throw new InsufficientMemoryException("Cannot allocate more than " + _MaxSizeinKB.ToString() + "KB"); else _Byte = new byte[nLength]; } public byte this[int nIndex] { get { return _Byte[nIndex]; } set { _Byte[nIndex] = value; } } }
Usage is as above in the question. Enjoy!
Thanks for pointing out.
I have updated the code the reflect the same.
--EDIT--
This is an update based upon the comment that I received. I missed the last sentence; that is,
The ByteArray class should hide this limitation and support allocating arrays larger than 64kThis update adds rest of the functionality; following is the updated ByteArray class:
class ByteArrayEx { private ListUsage is as follows:lstArray = new List (); public int _nSize; public int _nChunks; public const int _MaxSizeLimit = 65536;//3;//65536;//64K public ByteArrayEx(int nSize) { _nSize = nSize; if (nSize > _MaxSizeLimit) { //1. Calculate the number of 64K chunks int nChunks = nSize / _MaxSizeLimit; //130K; 64K + 64K + 2K //64 = 130/ //2 = 64k x 2 = 128k //Remaining = 128 - 130 = 2 //Remaining = nLengh - AllocatedSize int nAllocatedSize = 0; //2. Loop through the chunks for (int i = 0; i < nChunks; i++) { //3. Allocate the size nAllocatedSize = _MaxSizeLimit + nAllocatedSize; lstArray.Add(new byte[_MaxSizeLimit]); } //4. Allocate remaining bytes int nRemainingBytes = nSize - nAllocatedSize; if (nRemainingBytes > 0) lstArray.Add(new byte[nRemainingBytes]); _nChunks = lstArray.Count; } else lstArray.Add(new byte[nSize]); } public byte this[int nIndex] { get { //1. Get the index of array list item //2. Convert the incoming index to Index of byte array int nByteIndex = nIndex % _MaxSizeLimit; return ((byte[])(lstArray[GetBlockIndex(nIndex)]))[nByteIndex]; } set { //1. Get the index/block of array list //2. Convert the incoming index to Index of byte array int nBlockIndex = GetBlockIndex(nIndex); int nByteIndex = nIndex % _MaxSizeLimit; ((byte[])(lstArray[nBlockIndex]))[nByteIndex] = value; } } /// /// Block, represents the index of List item /// /// Incoming Index ///Actual Block Index private int GetBlockIndex(int nIndex) { int nAllocatedSize = 0; //2. Loop through the chunks int nBlockIndex = 0; for (int i = 0; i < _nChunks; i++) { //3. Allocate the size nAllocatedSize = _MaxSizeLimit + nAllocatedSize; if (nIndex <= nAllocatedSize) { nBlockIndex = i; break; } } return nBlockIndex; } }
ByteArray ba = new ByteArray (250000); // Create ba[150000] = 15; // Write byte byte x = ba[190000]; // Read byte
Couple of things to note; the 64K limit that is in the ByteArrayEx class can be anything; for instance:
In case of 64K of it would create single array to contain all the byte array elements.
In case of 128K (64K x 2 = 128K), it will create 2 items in the array list of size 64K each.
In case of 130K (64K x 2 + 2K more = 128K + 2K = 130K) it will create 3 items in the array list; this time, two items of size 64K and third item of size 2K. So array list would contain 3 byte arrays.
Hope you get the idea.
You can change the 64K limit to 32K or 8K or 3K, etc; and it will work as above.
Checkout the output, for the following given input:
class Program { static void Main(string[] args) { //Test 1 ByteArrayEx baTest1 = new ByteArrayEx(133120);// (64 + 64 + 2) * 1024; //130K or 133120 bytes baTest1[0] = (byte)'c';//Write Console.WriteLine(string.Format("Written byte:[{0}]", Convert.ToChar(baTest1[0]))); baTest1[133110] = (byte)'d';//Write more Console.WriteLine(string.Format("Written byte:[{0}]", Convert.ToChar(baTest1[133110]))); byte r = baTest1[133110];// be[133110]; Console.WriteLine(string.Format("Reading byte:[{0}]", Convert.ToChar(r))); Console.WriteLine(string.Format("Max Limit: {0}, Size: {1}, Chunks: {2}", ByteArrayEx._MaxSizeLimit, baTest1._nSize, baTest1._nChunks)); //Test 2 ByteArrayEx byteArray = new ByteArrayEx(250000); // Create byteArray[150000] = 15; // Write byte byte x = byteArray[190000]; // Read byte Console.WriteLine(string.Format("byte:[{0}]", x)); Console.WriteLine(string.Format("Max Limit: {0}, Size: {1}, Chunks: {2}", ByteArrayEx._MaxSizeLimit, byteArray._nSize, byteArray._nChunks)); Console.ReadKey(); } }
Note that, I have the List class to demostrate the functionality. You can add any class that provides array like functionality.
But your solution does not solve the following requirement:
ReplyDeleteThe ByteArray class should hide this limitation and support allocating arrays larger than 64k
You need to have multiple array for each 64k chunk.
Thanks for pointing out. I have updated the code to reflect the required functionality.
ReplyDelete