Пример #1
0
        public void Extend(ulong additionalLengthInBytes)
        {
            ulong currentSize = this.Length;

            if (m_attributeRecord is NonResidentAttributeRecord)
            {
                NonResidentAttributeData attributeData = new NonResidentAttributeData(m_volume, m_fileRecord, (NonResidentAttributeRecord)m_attributeRecord);
                attributeData.Extend(additionalLengthInBytes);
            }
            else
            {
                byte[] data              = ((ResidentAttributeRecord)m_attributeRecord).Data;
                ulong  finalDataLength   = (uint)data.Length + additionalLengthInBytes;
                ulong  finalRecordLength = (uint)m_attributeRecord.RecordLength + additionalLengthInBytes;
                if (finalRecordLength >= (ulong)m_volume.AttributeRecordLengthToMakeNonResident &&
                    m_attributeRecord.AttributeType != AttributeType.AttributeList) // We will create an attribute list with the right attribute form in advance.
                {
                    // Convert the attribute to non-resident
                    long clustersToAllocate = (long)Math.Ceiling((double)finalDataLength / m_volume.BytesPerCluster);
                    if (clustersToAllocate > m_volume.NumberOfFreeClusters)
                    {
                        throw new DiskFullException();
                    }
                    NonResidentAttributeRecord attributeRecord = NonResidentAttributeRecord.Create(m_attributeRecord.AttributeType, m_attributeRecord.Name);
                    NonResidentAttributeData   attributeData   = new NonResidentAttributeData(m_volume, null, attributeRecord);
                    attributeData.Extend(finalDataLength);
                    if (data.Length % m_volume.BytesPerCluster > 0)
                    {
                        int fillDataLength = m_volume.BytesPerCluster - (data.Length % m_volume.BytesPerCluster);
                        if ((uint)data.Length + (uint)fillDataLength < finalDataLength)
                        {
                            // Only the last cluster can be partially used, if this is not the last cluster, zero-fill it
                            data = ByteUtils.Concatenate(data, new byte[fillDataLength]);
                        }
                    }
                    attributeData.WriteClusters(0, data);
                    // Note that we overwrite the old attribute only after writing the non-resident data
                    if (m_fileRecord != null)
                    {
                        m_fileRecord.RemoveAttributeRecord(m_attributeRecord.AttributeType, m_attributeRecord.Name);
                        FileRecordHelper.InsertSorted(m_fileRecord.Attributes, attributeRecord);
                    }
                    m_attributeRecord = attributeRecord;
                }
                else
                {
                    int    currentLength = data.Length;
                    byte[] temp          = new byte[currentLength + (int)additionalLengthInBytes];
                    Array.Copy(data, temp, data.Length);
                    ((ResidentAttributeRecord)m_attributeRecord).Data = temp;
                }

                if (m_fileRecord != null)
                {
                    m_volume.UpdateFileRecord(m_fileRecord);
                }
            }
        }
Пример #2
0
        /// <returns>Record Index</returns>
        private long AllocateIndexRecord()
        {
            long?indexRecord = m_bitmapData.AllocateRecord();

            if (indexRecord == null)
            {
                long numberOfUsableBits = m_bitmapData.NumberOfUsableBits;
                m_indexAllocationData.Extend(m_rootRecord.BytesPerIndexRecord * ExtendGranularity);
                m_bitmapData.ExtendBitmap(ExtendGranularity);
                indexRecord = m_bitmapData.AllocateRecord(numberOfUsableBits);
            }
            return(indexRecord.Value);
        }
Пример #3
0
        /// <returns>Record Index</returns>
        private long AllocateIndexRecord()
        {
            uint transactionID = m_volume.LogClient.AllocateTransactionID();
            long?indexRecord   = m_bitmapData.AllocateRecord(transactionID);

            if (indexRecord == null)
            {
                long numberOfUsableBits = m_bitmapData.NumberOfUsableBits;
                m_indexAllocationData.Extend(m_rootRecord.BytesPerIndexRecord * ExtendGranularity);
                m_bitmapData.ExtendBitmap(ExtendGranularity);
                indexRecord = m_bitmapData.AllocateRecord(numberOfUsableBits, transactionID);
            }
            m_volume.LogClient.WriteForgetTransactionRecord(transactionID);
            return(indexRecord.Value);
        }