From acbbfafa07922b458506b91a58f3a082da453fd1 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 11 Feb 2023 22:33:44 -0700 Subject: Try to avoid unnecessary allocations in enum-types' String methods --- lib/btrfs/Makefile | 9 +-- lib/btrfs/btrfsitem/item_dir.go | 47 +++++++-------- lib/btrfs/btrfsitem/item_fileextent.go | 36 ++++++------ lib/btrfs/btrfsprim/itemtype.go | 104 +++++++++++++++++++++------------ lib/btrfs/btrfsprim/objid.go | 85 +++++++++++++-------------- lib/btrfs/btrfssum/csum.go | 35 +++++------ 6 files changed, 173 insertions(+), 143 deletions(-) diff --git a/lib/btrfs/Makefile b/lib/btrfs/Makefile index 015c3e1..b98a1b7 100644 --- a/lib/btrfs/Makefile +++ b/lib/btrfs/Makefile @@ -80,13 +80,10 @@ btrfsprim/itemtype.go: btrfsitem/items.txt $(MAKEFILE_LIST) sed -E 's,(.*)=([^:]*)(:.*)? (trivial|complex) (.*),\1_KEY ItemType=\2,' $< | uniq; \ echo ')'; \ echo 'func (t ItemType) String() string {'; \ - echo ' names := map[ItemType]string{'; \ - sed -E 's@(.*)=(.*) (trivial|complex) (.*)@\1_KEY: "\1",@' $< | sed 's/"UUID_/&KEY_/'; \ + echo ' switch t {'; \ + sed -E 's@(.*)=(.*) (trivial|complex) (.*)@case \1_KEY: return "\1"@' $< | sed 's/"UUID_/&KEY_/'; \ + echo ' default: return fmt.Sprintf("%d", t)'; \ echo ' }'; \ - echo ' if name, ok := names[t]; ok {'; \ - echo ' return name'; \ - echo ' }'; \ - echo ' return fmt.Sprintf("%d", t)'; \ echo '}'; \ } | gofmt >$@ files += btrfsprim/itemtype.go diff --git a/lib/btrfs/btrfsitem/item_dir.go b/lib/btrfs/btrfsitem/item_dir.go index 0f263d5..c1b3c09 100644 --- a/lib/btrfs/btrfsitem/item_dir.go +++ b/lib/btrfs/btrfsitem/item_dir.go @@ -84,33 +84,34 @@ func (o DirEntry) MarshalBinary() ([]byte, error) { type FileType uint8 const ( - FT_UNKNOWN FileType = 0 - FT_REG_FILE FileType = 1 - FT_DIR FileType = 2 - FT_CHRDEV FileType = 3 - FT_BLKDEV FileType = 4 - FT_FIFO FileType = 5 - FT_SOCK FileType = 6 - FT_SYMLINK FileType = 7 - FT_XATTR FileType = 8 + FT_UNKNOWN FileType = iota + FT_REG_FILE + FT_DIR + FT_CHRDEV + FT_BLKDEV + FT_FIFO + FT_SOCK + FT_SYMLINK + FT_XATTR - FT_MAX FileType = 9 + FT_MAX ) +var fileTypeNames = []string{ + "UNKNOWN", + "FILE", // NB: Just "FILE", despite corresponding to "REG_FILE" + "DIR", + "CHRDEV", + "BLKDEV", + "FIFO", + "SOCK", + "SYMLINK", + "XATTR", +} + func (ft FileType) String() string { - names := map[FileType]string{ - FT_UNKNOWN: "UNKNOWN", - FT_REG_FILE: "FILE", // XXX - FT_DIR: "DIR", - FT_CHRDEV: "CHRDEV", - FT_BLKDEV: "BLKDEV", - FT_FIFO: "FIFO", - FT_SOCK: "SOCK", - FT_SYMLINK: "SYMLINK", - FT_XATTR: "XATTR", - } - if name, ok := names[ft]; ok { - return name + if ft < FT_MAX { + return fileTypeNames[ft] } return fmt.Sprintf("DIR_ITEM.%d", uint8(ft)) } diff --git a/lib/btrfs/btrfsitem/item_fileextent.go b/lib/btrfs/btrfsitem/item_fileextent.go index ce6c45c..6b08897 100644 --- a/lib/btrfs/btrfsitem/item_fileextent.go +++ b/lib/btrfs/btrfsitem/item_fileextent.go @@ -106,6 +106,12 @@ const ( FILE_EXTENT_PREALLOC ) +var fileExtentTypeNames = []string{ + "inline", + "regular", + "prealloc", +} + func (o FileExtent) Size() (int64, error) { switch o.Type { case FILE_EXTENT_INLINE: @@ -118,14 +124,9 @@ func (o FileExtent) Size() (int64, error) { } func (fet FileExtentType) String() string { - names := map[FileExtentType]string{ - FILE_EXTENT_INLINE: "inline", - FILE_EXTENT_REG: "regular", - FILE_EXTENT_PREALLOC: "prealloc", - } - name, ok := names[fet] - if !ok { - name = "unknown" + name := "unknown" + if int(fet) < len(fileExtentTypeNames) { + name = fileExtentTypeNames[fet] } return fmt.Sprintf("%d (%s)", fet, name) } @@ -139,16 +140,17 @@ const ( COMPRESS_ZSTD ) +var compressionTypeNames = []string{ + "none", + "zlib", + "lzo", + "zstd", +} + func (ct CompressionType) String() string { - names := map[CompressionType]string{ - COMPRESS_NONE: "none", - COMPRESS_ZLIB: "zlib", - COMPRESS_LZO: "lzo", - COMPRESS_ZSTD: "zstd", - } - name, ok := names[ct] - if !ok { - name = "unknown" + name := "unknown" + if int(ct) < len(compressionTypeNames) { + name = compressionTypeNames[ct] } return fmt.Sprintf("%d (%s)", ct, name) } diff --git a/lib/btrfs/btrfsprim/itemtype.go b/lib/btrfs/btrfsprim/itemtype.go index dba7ced..f33179a 100644 --- a/lib/btrfs/btrfsprim/itemtype.go +++ b/lib/btrfs/btrfsprim/itemtype.go @@ -42,42 +42,72 @@ const ( ) func (t ItemType) String() string { - names := map[ItemType]string{ - BLOCK_GROUP_ITEM_KEY: "BLOCK_GROUP_ITEM", - CHUNK_ITEM_KEY: "CHUNK_ITEM", - DEV_EXTENT_KEY: "DEV_EXTENT", - DEV_ITEM_KEY: "DEV_ITEM", - DIR_INDEX_KEY: "DIR_INDEX", - DIR_ITEM_KEY: "DIR_ITEM", - EXTENT_CSUM_KEY: "EXTENT_CSUM", - EXTENT_DATA_KEY: "EXTENT_DATA", - EXTENT_DATA_REF_KEY: "EXTENT_DATA_REF", - EXTENT_ITEM_KEY: "EXTENT_ITEM", - FREE_SPACE_BITMAP_KEY: "FREE_SPACE_BITMAP", - FREE_SPACE_EXTENT_KEY: "FREE_SPACE_EXTENT", - FREE_SPACE_INFO_KEY: "FREE_SPACE_INFO", - INODE_ITEM_KEY: "INODE_ITEM", - INODE_REF_KEY: "INODE_REF", - METADATA_ITEM_KEY: "METADATA_ITEM", - ORPHAN_ITEM_KEY: "ORPHAN_ITEM", - PERSISTENT_ITEM_KEY: "PERSISTENT_ITEM", - QGROUP_INFO_KEY: "QGROUP_INFO", - QGROUP_LIMIT_KEY: "QGROUP_LIMIT", - QGROUP_RELATION_KEY: "QGROUP_RELATION", - QGROUP_STATUS_KEY: "QGROUP_STATUS", - ROOT_BACKREF_KEY: "ROOT_BACKREF", - ROOT_ITEM_KEY: "ROOT_ITEM", - ROOT_REF_KEY: "ROOT_REF", - SHARED_BLOCK_REF_KEY: "SHARED_BLOCK_REF", - SHARED_DATA_REF_KEY: "SHARED_DATA_REF", - TREE_BLOCK_REF_KEY: "TREE_BLOCK_REF", - UNTYPED_KEY: "UNTYPED", - UUID_RECEIVED_SUBVOL_KEY: "UUID_KEY_RECEIVED_SUBVOL", - UUID_SUBVOL_KEY: "UUID_KEY_SUBVOL", - XATTR_ITEM_KEY: "XATTR_ITEM", + switch t { + case BLOCK_GROUP_ITEM_KEY: + return "BLOCK_GROUP_ITEM" + case CHUNK_ITEM_KEY: + return "CHUNK_ITEM" + case DEV_EXTENT_KEY: + return "DEV_EXTENT" + case DEV_ITEM_KEY: + return "DEV_ITEM" + case DIR_INDEX_KEY: + return "DIR_INDEX" + case DIR_ITEM_KEY: + return "DIR_ITEM" + case EXTENT_CSUM_KEY: + return "EXTENT_CSUM" + case EXTENT_DATA_KEY: + return "EXTENT_DATA" + case EXTENT_DATA_REF_KEY: + return "EXTENT_DATA_REF" + case EXTENT_ITEM_KEY: + return "EXTENT_ITEM" + case FREE_SPACE_BITMAP_KEY: + return "FREE_SPACE_BITMAP" + case FREE_SPACE_EXTENT_KEY: + return "FREE_SPACE_EXTENT" + case FREE_SPACE_INFO_KEY: + return "FREE_SPACE_INFO" + case INODE_ITEM_KEY: + return "INODE_ITEM" + case INODE_REF_KEY: + return "INODE_REF" + case METADATA_ITEM_KEY: + return "METADATA_ITEM" + case ORPHAN_ITEM_KEY: + return "ORPHAN_ITEM" + case PERSISTENT_ITEM_KEY: + return "PERSISTENT_ITEM" + case QGROUP_INFO_KEY: + return "QGROUP_INFO" + case QGROUP_LIMIT_KEY: + return "QGROUP_LIMIT" + case QGROUP_RELATION_KEY: + return "QGROUP_RELATION" + case QGROUP_STATUS_KEY: + return "QGROUP_STATUS" + case ROOT_BACKREF_KEY: + return "ROOT_BACKREF" + case ROOT_ITEM_KEY: + return "ROOT_ITEM" + case ROOT_REF_KEY: + return "ROOT_REF" + case SHARED_BLOCK_REF_KEY: + return "SHARED_BLOCK_REF" + case SHARED_DATA_REF_KEY: + return "SHARED_DATA_REF" + case TREE_BLOCK_REF_KEY: + return "TREE_BLOCK_REF" + case UNTYPED_KEY: + return "UNTYPED" + case UUID_RECEIVED_SUBVOL_KEY: + return "UUID_KEY_RECEIVED_SUBVOL" + case UUID_SUBVOL_KEY: + return "UUID_KEY_SUBVOL" + case XATTR_ITEM_KEY: + return "XATTR_ITEM" + default: + return fmt.Sprintf("%d", t) } - if name, ok := names[t]; ok { - return name - } - return fmt.Sprintf("%d", t) } diff --git a/lib/btrfs/btrfsprim/objid.go b/lib/btrfs/btrfsprim/objid.go index 8ca1fbb..1aea030 100644 --- a/lib/btrfs/btrfsprim/objid.go +++ b/lib/btrfs/btrfsprim/objid.go @@ -54,13 +54,45 @@ const ( EMPTY_SUBVOL_DIR_OBJECTID ObjID = 2 ) +var ( + objidCommonNames = map[ObjID]string{ + BALANCE_OBJECTID: "BALANCE", + ORPHAN_OBJECTID: "ORPHAN", + TREE_LOG_OBJECTID: "TREE_LOG", + TREE_LOG_FIXUP_OBJECTID: "TREE_LOG_FIXUP", + TREE_RELOC_OBJECTID: "TREE_RELOC", + DATA_RELOC_TREE_OBJECTID: "DATA_RELOC_TREE", + EXTENT_CSUM_OBJECTID: "EXTENT_CSUM", + FREE_SPACE_OBJECTID: "FREE_SPACE", + FREE_INO_OBJECTID: "FREE_INO", + MULTIPLE_OBJECTIDS: "MULTIPLE", + } + objidDevTreeNames = map[ObjID]string{ + DEV_STATS_OBJECTID: "DEV_STATS", + } + objidChunkTreeNames = map[ObjID]string{ + DEV_ITEMS_OBJECTID: "DEV_ITEMS", + FIRST_CHUNK_TREE_OBJECTID: "FIRST_CHUNK_TREE", + } + objidRootTreeNames = map[ObjID]string{ + ROOT_TREE_OBJECTID: "ROOT_TREE", + EXTENT_TREE_OBJECTID: "EXTENT_TREE", + CHUNK_TREE_OBJECTID: "CHUNK_TREE", + DEV_TREE_OBJECTID: "DEV_TREE", + FS_TREE_OBJECTID: "FS_TREE", + ROOT_TREE_DIR_OBJECTID: "ROOT_TREE_DIR", + CSUM_TREE_OBJECTID: "CSUM_TREE", + QUOTA_TREE_OBJECTID: "QUOTA_TREE", + UUID_TREE_OBJECTID: "UUID_TREE", + FREE_SPACE_TREE_OBJECTID: "FREE_SPACE_TREE", + BLOCK_GROUP_TREE_OBJECTID: "BLOCK_GROUP_TREE", + } +) + func (id ObjID) Format(tree ObjID) string { switch tree { case DEV_TREE_OBJECTID: - names := map[ObjID]string{ - DEV_STATS_OBJECTID: "DEV_STATS", - } - if name, ok := names[id]; ok { + if name, ok := objidDevTreeNames[id]; ok { return name } return fmt.Sprintf("%d", int64(id)) @@ -75,51 +107,18 @@ func (id ObjID) Format(tree ObjID) string { case UUID_TREE_OBJECTID: return fmt.Sprintf("%#016x", uint64(id)) case CHUNK_TREE_OBJECTID: - names := map[ObjID]string{ - BALANCE_OBJECTID: "BALANCE", - ORPHAN_OBJECTID: "ORPHAN", - TREE_LOG_OBJECTID: "TREE_LOG", - TREE_LOG_FIXUP_OBJECTID: "TREE_LOG_FIXUP", - TREE_RELOC_OBJECTID: "TREE_RELOC", - DATA_RELOC_TREE_OBJECTID: "DATA_RELOC_TREE", - EXTENT_CSUM_OBJECTID: "EXTENT_CSUM", - FREE_SPACE_OBJECTID: "FREE_SPACE", - FREE_INO_OBJECTID: "FREE_INO", - MULTIPLE_OBJECTIDS: "MULTIPLE", - - DEV_ITEMS_OBJECTID: "DEV_ITEMS", - FIRST_CHUNK_TREE_OBJECTID: "FIRST_CHUNK_TREE", + if name, ok := objidCommonNames[id]; ok { + return name } - if name, ok := names[id]; ok { + if name, ok := objidChunkTreeNames[id]; ok { return name } return fmt.Sprintf("%d", int64(id)) default: - names := map[ObjID]string{ - BALANCE_OBJECTID: "BALANCE", - ORPHAN_OBJECTID: "ORPHAN", - TREE_LOG_OBJECTID: "TREE_LOG", - TREE_LOG_FIXUP_OBJECTID: "TREE_LOG_FIXUP", - TREE_RELOC_OBJECTID: "TREE_RELOC", - DATA_RELOC_TREE_OBJECTID: "DATA_RELOC_TREE", - EXTENT_CSUM_OBJECTID: "EXTENT_CSUM", - FREE_SPACE_OBJECTID: "FREE_SPACE", - FREE_INO_OBJECTID: "FREE_INO", - MULTIPLE_OBJECTIDS: "MULTIPLE", - - ROOT_TREE_OBJECTID: "ROOT_TREE", - EXTENT_TREE_OBJECTID: "EXTENT_TREE", - CHUNK_TREE_OBJECTID: "CHUNK_TREE", - DEV_TREE_OBJECTID: "DEV_TREE", - FS_TREE_OBJECTID: "FS_TREE", - ROOT_TREE_DIR_OBJECTID: "ROOT_TREE_DIR", - CSUM_TREE_OBJECTID: "CSUM_TREE", - QUOTA_TREE_OBJECTID: "QUOTA_TREE", - UUID_TREE_OBJECTID: "UUID_TREE", - FREE_SPACE_TREE_OBJECTID: "FREE_SPACE_TREE", - BLOCK_GROUP_TREE_OBJECTID: "BLOCK_GROUP_TREE", + if name, ok := objidCommonNames[id]; ok { + return name } - if name, ok := names[id]; ok { + if name, ok := objidRootTreeNames[id]; ok { return name } return fmt.Sprintf("%d", int64(id)) diff --git a/lib/btrfs/btrfssum/csum.go b/lib/btrfs/btrfssum/csum.go index bce43f9..157371e 100644 --- a/lib/btrfs/btrfssum/csum.go +++ b/lib/btrfs/btrfssum/csum.go @@ -58,29 +58,30 @@ const ( TYPE_BLAKE2 ) +var csumTypeNames = []string{ + "crc32c", + "xxhash64", + "sha256", + "blake2", +} + +var csumTypeSizes = []int{ + 4, + 8, + 32, + 32, +} + func (typ CSumType) String() string { - names := map[CSumType]string{ - TYPE_CRC32: "crc32c", - TYPE_XXHASH: "xxhash64", - TYPE_SHA256: "sha256", - TYPE_BLAKE2: "blake2", - } - if name, ok := names[typ]; ok { - return name + if int(typ) < len(csumTypeNames) { + return csumTypeNames[typ] } return fmt.Sprintf("%d", typ) } func (typ CSumType) Size() int { - //nolint:gomnd // This is where we define the magic numbers. - sizes := map[CSumType]int{ - TYPE_CRC32: 4, - TYPE_XXHASH: 8, - TYPE_SHA256: 32, - TYPE_BLAKE2: 32, - } - if size, ok := sizes[typ]; ok { - return size + if int(typ) < len(csumTypeSizes) { + return csumTypeSizes[typ] } return len(CSum{}) } -- cgit v1.2.3-2-g168b