public IndexRootRecord(byte[] buffer, int offset) : base(buffer, offset) { IndexedAttributeType = (AttributeType)LittleEndianConverter.ToUInt32(this.Data, 0x00); CollationRule = (CollationRule)LittleEndianConverter.ToUInt32(this.Data, 0x04); IndexAllocationEntryLength = LittleEndianConverter.ToUInt32(this.Data, 0x08); ClustersPerIndexRecord = ByteReader.ReadByte(this.Data, 0x0C); // 3 zero bytes (padding to 8-byte boundary) EntriesOffset = LittleEndianConverter.ToUInt32(this.Data, 0x10); IndexLength = LittleEndianConverter.ToUInt32(this.Data, 0x14); AllocatedLength = LittleEndianConverter.ToUInt32(this.Data, 0x18); IndexFlags = (IndexRootFlags)ByteReader.ReadByte(this.Data, 0x1C); // 3 zero bytes (padding to 8-byte boundary) if (Name == FileNameIndexName) { int position = 0x10 + (int)EntriesOffset; if (IsLargeIndex) { IndexNode node = new IndexNode(this.Data, position); IndexEntries = node.Entries; } else { FileNameIndexLeafNode leaf = new FileNameIndexLeafNode(this.Data, position); FileNameEntries = leaf.Entries; } } }
public AttributeDefinitionEntry(byte[] buffer, int offset) { AttributeName = ByteReader.ReadUTF16String(buffer, offset + 0x00, AttributeNameLength).TrimEnd(new char[] { '\0' }); AttributeType = (AttributeType)LittleEndianConverter.ToUInt32(buffer, offset + 0x80); DisplayRule = LittleEndianConverter.ToUInt32(buffer, offset + 0x84); CollationRule = (CollationRule)LittleEndianConverter.ToUInt32(buffer, offset + 0x88); Flags = (AttributeDefinitionFlags)LittleEndianConverter.ToUInt32(buffer, offset + 0x8C); MinimumLength = LittleEndianConverter.ToUInt64(buffer, offset + 0x90); MaximumLength = LittleEndianConverter.ToUInt64(buffer, offset + 0x98); }
public IndexRootRecord(byte[] buffer, int offset) : base(buffer, offset) { IndexedAttributeType = (AttributeType)LittleEndianConverter.ToUInt32(this.Data, 0x00); CollationRule = (CollationRule)LittleEndianConverter.ToUInt32(this.Data, 0x04); BytesPerIndexRecord = LittleEndianConverter.ToUInt32(this.Data, 0x08); BlocksPerIndexRecord = ByteReader.ReadByte(this.Data, 0x0C); // 3 zero bytes (padding to 8-byte boundary) m_indexHeader = new IndexHeader(this.Data, 0x10); int entriesOffset = IndexHeaderOffset + (int)m_indexHeader.EntriesOffset; IndexEntries = IndexEntry.ReadIndexEntries(this.Data, entriesOffset); }
public static int FindIndexInLeafNode(List <IndexEntry> entries, byte[] key, CollationRule collationRule) { if (entries.Count == 0) { return(-1); } int lowerIndex = 0; int upperIndex = entries.Count - 1; int comparisonResult; while (lowerIndex < upperIndex) { int middleIndex = (lowerIndex + upperIndex) / 2; IndexEntry middle = entries[middleIndex]; comparisonResult = Compare(middle.Key, key, collationRule); if (comparisonResult == 0) { return(middleIndex); } else if (comparisonResult > 0) // middle > key { upperIndex = middleIndex - 1; } else // middle < key { lowerIndex = middleIndex + 1; } } comparisonResult = Compare(entries[lowerIndex].Key, key, collationRule); if (comparisonResult == 0) { return(lowerIndex); } else { return(-1); } }
public static int Compare(byte[] key1, byte[] key2, CollationRule collationRule) { switch (collationRule) { case CollationRule.Filename: { string str1 = FileNameRecord.ReadFileName(key1, 0); string str2 = FileNameRecord.ReadFileName(key2, 0); return(String.Compare(str1, str2, StringComparison.OrdinalIgnoreCase)); } case CollationRule.UnicodeString: { string str1 = Encoding.Unicode.GetString(key1); string str2 = Encoding.Unicode.GetString(key2); return(String.Compare(str1, str2, StringComparison.OrdinalIgnoreCase)); } default: throw new NotImplementedException(); } }
public static void InitializeIndexRoot(IndexRootRecord indexRoot, AttributeType indexedAttributeType, CollationRule collationRule, int bytesPerIndexRecord, int bytesPerCluster) { indexRoot.IndexedAttributeType = indexedAttributeType; indexRoot.CollationRule = collationRule; indexRoot.BytesPerIndexRecord = (uint)bytesPerIndexRecord; if (bytesPerIndexRecord >= bytesPerCluster) { indexRoot.BlocksPerIndexRecord = (byte)(bytesPerIndexRecord / bytesPerCluster); } else { indexRoot.BlocksPerIndexRecord = (byte)(bytesPerIndexRecord / IndexRecord.BytesPerIndexRecordBlock); } }
public static int FindIndexInParentNode(List <IndexEntry> entries, byte[] key, CollationRule collationRule) { if (entries.Count == 0) { throw new ArgumentException("Parent Index Record must contain at least 1 entry"); } if (entries.Count == 1) { // The root can contain a single entry pointing to a leaf record return(0); } int lowerIndex = 0; int upperIndex = entries.Count - 2; int comparisonResult; while (lowerIndex < upperIndex) { int middleIndex = (lowerIndex + upperIndex) / 2; IndexEntry middle = entries[middleIndex]; comparisonResult = Compare(middle.Key, key, collationRule); if (comparisonResult == 0) { return(middleIndex); } else if (comparisonResult > 0) // middle > key { upperIndex = middleIndex - 1; } else // middle < key { lowerIndex = middleIndex + 1; } } // At this point any entry following 'middle' is greater than 'key', // and any entry preceding 'middle' is lesser than 'key'. // So we either put 'key' before or after 'middle'. comparisonResult = Compare(entries[lowerIndex].Key, key, collationRule); if (comparisonResult < 0) // middle < key { return(lowerIndex + 1); } else { return(lowerIndex); } }
public static int FindIndexForSortedInsert(List <IndexEntry> entries, byte[] key, CollationRule collationRule) { if (entries.Count == 0) { return(0); } int lowerIndex = 0; int upperIndex = entries.Count - 1; int comparisonResult; while (lowerIndex < upperIndex) { int middleIndex = (lowerIndex + upperIndex) / 2; IndexEntry middle = entries[middleIndex]; comparisonResult = Compare(middle.Key, key, collationRule); if (comparisonResult == 0) { return(middleIndex); } else if (comparisonResult > 0) // middle > key { upperIndex = middleIndex - 1; } else // middle < key { lowerIndex = middleIndex + 1; } } // At this point any entry following 'middle' is greater than 'key', // and any entry preceding 'middle' is lesser than 'key'. // So we either put 'key' before or after 'middle'. comparisonResult = Compare(entries[lowerIndex].Key, key, collationRule); if (comparisonResult < 0) // middle < key { return(lowerIndex + 1); } else { return(lowerIndex); } }