예제 #1
0
        public void AddFile(string filePath, byte[] fileBytes)
        {
            if (Mode == FileSystemMode.Read)
            {
                return;
            }

            int          usageSize    = GetFileUsageSize(fileBytes.Length);
            FragmentData fragmentData = fragment.Get(usageSize);

            if (fragmentData == null)
            {
                long start = content.Write(fileBytes);
                if (usageSize - fileBytes.Length > 0)
                {
                    content.Write(new byte[usageSize - fileBytes.Length]);
                }

                chunk.Add(filePath, start, fileBytes.Length, usageSize);
            }
            else
            {
                content.Write(fragmentData.StartPosition, fileBytes);

                chunk.Add(filePath, fragmentData.StartPosition, fileBytes.Length, usageSize);

                fragmentData.StartPosition += usageSize;
                fragmentData.UsageSize     -= usageSize;

                fragment.Update(fragmentData);
            }
        }
예제 #2
0
        public void Update(FragmentData fragmentData)
        {
            if (fragmentData.UsageSize > 0)
            {
                sortedSizeFragments.Remove(fragmentData);

                int sizeInsertIndex = FindSizeInsertIndex(0, sortedSizeFragments.Count - 1, fragmentData.UsageSize);
                sortedSizeFragments.Insert(sizeInsertIndex, fragmentData);
            }
            else
            {
                sortedStartFragments.Remove(fragmentData);
                sortedSizeFragments.Remove(fragmentData);
            }
        }
예제 #3
0
        public unsafe FileSystemResultCode ReadFromStream(Stream stream)
        {
            byte[] bytes = new byte[FragmentData.SIZE];
            if (stream.Read(bytes, 0, sizeof(int)) != sizeof(int))
            {
                return(FileSystemResultCode.FragmentByteLengthError);
            }

            int len = 0;

            fixed(byte *b = &bytes[0])
            {
                len = *((int *)b);
            }

            for (int i = 0; i < len; ++i)
            {
                if (stream.Read(bytes, 0, bytes.Length) != bytes.Length)
                {
                    return(FileSystemResultCode.FragmentDataByteLengthError);
                }

                fixed(byte *c = &bytes[0])
                {
                    long start = *((long *)c);
                    int  size  = *((int *)(c + sizeof(long)));

                    FragmentData data = new FragmentData()
                    {
                        StartPosition = start, UsageSize = size
                    };

                    sortedStartFragments.Add(data);
                }
            }

            if (sortedStartFragments.Count != len)
            {
                return(FileSystemResultCode.FragmentDataCountError);
            }
            return(FileSystemResultCode.Success);
        }
예제 #4
0
        public void Add(long start, int size)
        {
            if (sortedStartFragments.Count == 0)
            {
                FragmentData fragmentData = new FragmentData()
                {
                    StartPosition = start,
                    UsageSize     = size,
                };

                sortedStartFragments.Add(fragmentData);
                sortedSizeFragments.Add(fragmentData);
            }
            else
            {
                int startInsertIndex = FindStartInsertIndex(0, sortedStartFragments.Count - 1, start);

                FragmentData preFragment  = startInsertIndex == 0 ? null : sortedStartFragments[startInsertIndex - 1];
                FragmentData nextFragment = startInsertIndex == sortedStartFragments.Count ? null : sortedStartFragments[startInsertIndex];

                bool isConcatPre = false;
                if (preFragment != null && preFragment.StartPosition + preFragment.UsageSize == start)
                {
                    isConcatPre = true;
                }
                bool isConcatNext = false;
                if (nextFragment != null && start + size == nextFragment.StartPosition)
                {
                    isConcatNext = true;
                }

                FragmentData fragment = null;
                if (!isConcatPre && !isConcatNext)
                {
                    fragment = new FragmentData()
                    {
                        StartPosition = startInsertIndex,
                        UsageSize     = size,
                    };
                    sortedStartFragments.Insert(startInsertIndex, fragment);
                }
                else if (isConcatNext && isConcatPre)
                {
                    preFragment.UsageSize += size + nextFragment.UsageSize;
                    sortedStartFragments.Remove(nextFragment);

                    sortedSizeFragments.Remove(preFragment);
                    sortedSizeFragments.Remove(nextFragment);

                    fragment = preFragment;
                }
                else if (isConcatNext)
                {
                    nextFragment.StartPosition -= size;
                    sortedSizeFragments.Remove(nextFragment);

                    fragment = nextFragment;
                }
                else if (isConcatPre)
                {
                    preFragment.UsageSize += size;
                    sortedSizeFragments.Remove(preFragment);

                    fragment = preFragment;
                }

                if (sortedSizeFragments.Count == 0)
                {
                    sortedSizeFragments.Add(fragment);
                }
                else
                {
                    int sizeInsertIndex = FindSizeInsertIndex(0, sortedSizeFragments.Count - 1, fragment.UsageSize);
                    sortedSizeFragments.Insert(sizeInsertIndex, fragment);
                }
            }
        }