2023年11月15日

[筆記] inotify Info: Tracking What Apps Consume Your File Watcher Resource

不知道大家有沒有用過會幫你追蹤檔案的變動狀況 (更新/刪除) 的程式,在一偵測到檔案有變動時就會提醒/自動更新到最新的結果。在 Linux 上 kernel 那邊有提供一套 C API 專門處理這件事,叫做 inotify,利用這一組 API 我們就能輕鬆的在 Linux 上的程式做到一樣的偵測。

然而 inotify 針對每個使用者其實是設有上限的 (是一個使用者,而非一個程式),如果程式因意外掛著沒有被清掉,或是沒寫好導致一直占用資源,這將導致後續的程式因為觸發上限導致失敗。這時就需要去找出到底是哪些 process 占用掉太多 inotify 資源。

2023年10月4日

[C++] Branchless Singly Linked List

最近同事分享了一個一小段在新增 node 到 singly linked list 時不用判斷 head/tail 是否為 nullptr 的寫法,因為滿有趣的,所以分享一下

2022年11月23日

[python] Record Function Call

最近因為需要在程式中埋下紀錄使用者過程中用到了那些 function,這樣方便日後追蹤重現結果。當然最簡單的方法是在每個 function 內都明確地用 logger 之類的寫進 log 裡,不過 python 有更簡單更不容易出錯的方式可以達到效果,因為用 logger 很容易在未來程式改版時有所疏漏。

方法基本上有三種:proxy, build-in __getattribute__(), decorator

2022年9月13日

[C++] Metaprogram for Getting Bit Size & Converting to Power of 2

大家有沒有遇過這種狀況呢? 一些資料結構 (ex: heap, binary tree) 的節點數量往往是 2 的冪次方 - 1;或者是為了程式效率,把陣列或是 struct 的大小設定成 2 的冪次方。以往在寫這類數值時通常會利用 #define 或者是 constexpr 等等之類的方法把這種數值變成某個有意義的變數,像是這樣:

constexpr int BITSIZE = 10;
constexpr int BUFSIZE = 1024;

但這種時候會遇到一個小麻煩:開發過程中為了程式效率會常常調整這些數值,所以為了盡可能減少錯誤會有各種方式來做這些基礎設定。比方說 BUFSIZE 就可以改成 (1 << BITSIZE) 來避免改了 BITSIZE 忘記改掉 BUFSIZE。

當然,現在 compiler 已經很厲害了,如果某些基礎設定值在編譯期 (compile-time) 就是常數,現在也有不少方法可以讓後續的衍伸運算也都變成編譯期的常數,從而減少執行期的時間。這篇文章要做的主要是介紹用 metaprogramming 把這些運算通通轉成編譯期的常數。

2022年6月17日

[C++] Partial Template Specialization of class Member Function

事情是這樣的,有人問我他想做到這件事:

enum class Enum {A, B, C ... };
template <Enum E, int N>
struct MyStruct {
    void func();
};

template <int N>
void MyStruct<Enum::A, N>::func() {...}

看完後我就說了,你想做的事 function 的偏特化,這在 C++ 是不被允許的,所以當然會編譯失敗囉
當然,下一個問題就是:那要怎麼做?

以下提供幾個方法 (先不考慮整個 class 重構把 template argument 拆掉) 

2022年1月5日

[Python] Use String As Variable Name

最近做的東西有個需求有點特別,在程式跑的過程中會在某一步讓使用者可以看看目前有哪些變數他可以用,然後讓他選擇要抓哪個變數出來做後續處理,概念上有點像是 gdb 的 info variables

然而這就表示我們程式中會需要接受一個使用者輸入的字串當作 key 去存取變數,所幸程式是用 python 寫的,所以類似的方法不難做。

2021年5月14日

[C++] Error Out Calling Overloaded Function with Type Conversion

故事的情境是這樣的:

某支 function 的設計,假設叫 func 好了,他只有一個參數 param,但是 param 有多種可能的型別,比方說 int, bool, ... 等等,根據不同的型別實作上會稍有不同,為此根據 param 的不同型別提供不同的 overloading 實作,讓使用者可以無需顧慮型別問題。

問題是,當今天使用者傳進 param 的型別,假設是 char,根據預期應該要去呼叫對應到 char 的實作,但是目前的實作中並沒有提供,理想上是應該對此另行提供一個符合 char 的實作,然後根據 C++ overloading resolution 的機制,此時會去呼叫 param 型別是 int 的實作從而導致可能有非預期的結果。

理想上此時應該在開發階段時就以某種方式告知開發者此處有缺漏須補足,但,該怎麼做?

2020年12月15日

[C] Implement SHA-1

最近因為工作需要把一串字串經過處理後變成另一個長度最多 48-byte 的唯一的字串,能做到這類事情理所當然地就會往 MD5、SHA-1 這類 hash function 去找,而且因為不是要用作加密金鑰,對於安全性的要求並不高,所以後來就選了 SHA-1 當作目標。

實際看了下演算法,其實超簡單的...雖然會有一些細節要特別注意,但整體上的實作相當容易。以下就一一說明要注意的細節,C code 就放在最後面供參囉。

2020年11月20日

[C++] Calling Unexpected Member Function when The Version of Library Header File is Older Than Shared Library

同事最近遇到一個神奇問題,簡單來說就是他修改了一個會 release 給客戶或其他產品的 library,在裡面新增了一個 API。但照理說這個剛 release 的 API 還沒有人用到才對,卻在一系列的 regression 中發現它竟然被 call 到,而且造成程式 crash?! 從此展開他的 debug 之旅...

2020年11月12日

[C] Alignment Via Bitwise Operations

有時候會因為 performance / memory access 等等考量需要把不足 4/8 bytes 的資料 align 到 4/8 bytes,做法很多個,這邊列個最近看到的作法以資紀錄。