Browse Source

reduce code bloat in the DecodeOpenMode function

The loop version works as fast as unrolled one. But the binary code size is about 7 times smaller.
9c014c6ba2ab744670f9ac2fe3bf57942e01b0a1
swarmer 11 months ago
parent
commit
e646c0d6f3
1 changed files with 56 additions and 44 deletions
  1. 56 44
      util/system/file.cpp

+ 56 - 44
util/system/file.cpp

@@ -832,52 +832,64 @@ TString DecodeOpenMode(ui32 mode0) {
 
     TStringBuilder r;
 
-#define F(flag)                   \
-    if ((mode & flag) == flag) {  \
-        mode &= ~flag;            \
-        if (r) {                  \
-            r << TStringBuf("|"); \
-        }                         \
-        r << TStringBuf(#flag);   \
-    }
-
-    F(RdWr)
-    F(RdOnly)
-    F(WrOnly)
-
-    F(CreateAlways)
-    F(CreateNew)
-    F(OpenAlways)
-    F(TruncExisting)
-    F(ForAppend)
-    F(Transient)
-    F(CloseOnExec)
-
-    F(Temp)
-    F(Sync)
-    F(Direct)
-    F(DirectAligned)
-    F(Seq)
-    F(NoReuse)
-    F(NoReadAhead)
-
-    F(AX)
-    F(AR)
-    F(AW)
-    F(ARW)
-
-    F(AXOther)
-    F(AWOther)
-    F(AROther)
-    F(AXGroup)
-    F(AWGroup)
-    F(ARGroup)
-    F(AXUser)
-    F(AWUser)
-    F(ARUser)
+    struct TFlagCombo {
+        ui32 Value;
+        TStringBuf Name;
+    };
+
+    static constexpr TFlagCombo knownFlagCombos[]{
+
+#define F(flag) {flag, #flag}
+
+        F(RdWr),
+        F(RdOnly),
+        F(WrOnly),
+
+        F(CreateAlways),
+        F(CreateNew),
+        F(OpenAlways),
+        F(TruncExisting),
+        F(ForAppend),
+        F(Transient),
+        F(CloseOnExec),
+
+        F(Temp),
+        F(Sync),
+        F(Direct),
+        F(DirectAligned),
+        F(Seq),
+        F(NoReuse),
+        F(NoReadAhead),
+
+        F(AX),
+        F(AR),
+        F(AW),
+        F(ARW),
+
+        F(AXOther),
+        F(AWOther),
+        F(AROther),
+        F(AXGroup),
+        F(AWGroup),
+        F(ARGroup),
+        F(AXUser),
+        F(AWUser),
+        F(ARUser),
 
 #undef F
 
+    };
+
+    for (const auto& [flag, name] : knownFlagCombos) {
+        if ((mode & flag) == flag) {
+            mode &= ~flag;
+            if (r) {
+                r << '|';
+            }
+            r << name;
+        }
+    }
+
     if (mode != 0) {
         if (r) {
             r << TStringBuf("|");
@@ -890,7 +902,7 @@ TString DecodeOpenMode(ui32 mode0) {
         return "0";
     }
 
-    return r;
+    return std::move(r);
 }
 
 class TFile::TImpl: public TAtomicRefCount<TImpl> {