如何來管理空閒資源,顯而易見的是組織成乙個雙向鍊錶,稱作freelist,然後每次從該鍊錶上取出乙個,釋放的時候再放回去。為了減少碎片,最好的策略就是優先分配最近釋放掉的那個,如果能考慮合併的話,類似夥伴系統那樣,就再好不過了,本文給出的是乙個通用的可以將資源對映到乙個整型id的資源分配演算法,完全基於乙個陣列,不需要記憶體管理,也不需要分配結構體。
組織鍊錶的時候,記憶體管理要耗去大量的工作,前向指標和後向指標的修改前提是必須有這些指標。典型的資料結構就是linux核心的list_head結構體。但是對於靜態的類似點陣圖的資源並不適合用list_head來組織,因為這類資源本身可以對映到一塊連續的以自然數計數的id,比較典型的就是磁碟的空閒塊,連續記憶體塊的分配。
既然資源位置是連續的,它就一定能用連續的自然數來表示,那麼所有的資源就可以表示成乙個陣列了-其對映成自然數的id的陣列,記為arraya。
接下來我們需要另外乙個陣列來表示空閒鍊錶,記為arrayb。
接下來的然後,就是構造arrayb了...arrayb的大小等於arraya大小加上1,多出來的這個元素可以作為不動點存在,它是不會被分配出去的。arrayb的元素的大小是arraya陣列大小佔據位元組數的兩倍,是為了在乙個元素中儲存兩個index,比如陣列大小可以用8位資料表示,即最多256個元素,那麼arrayb的元素就應該是2*8這麼大的,舉例說明:
陣列大小:short-最多65536個元素
arraya的陣列定義:int arraya[max];max最大65536
arrayb的陣列定義:int arrayb;int型為兩個short型
結構體形象化表示arrayb:
#define num 8
struct freehl ;
struct freehl freelist[num+1];
相當於將arrayb劈開成了兩半。
然後就可以在連續的陣列空間進行鏈結操作了。實際上這個陣列表示的freelist和指標表示的prev,next的freelist是一致的,陣列下標也是乙個指標,只是在陣列表示的freelist中,使用的是相對指標偏移而已,表示為下標!
下面就是乙個演算法實現問題了,很簡單。在freelist中分配了乙個index後,需要修改其前向index的後向index以及後向index的前向index,釋放過程和分配過程相反。**如下:
short data[num]; //是為arraya
struct freehl freelist[num+1]; /是為arrayb
//表示乙個下乙個分配的index;
unsigned int position = 0;
//全域性的一次性初始化,注意,如果是序列化到了檔案,
//則不能再次初始化了,應該從檔案反序列化來初始化。
void list_init()
position = 0;
}//分配介面
int nalloc()
//更新當前index前向index的後向index
freelist[freelist[ret_index].high_preindex].low_nextindex = next_index;
//更新當前index後向index的前向index
freelist[freelist[ret_index].low_nextindex].high_preindex = pre_index;
return ret_index;
}//釋放介面
int nfree(unsigned int id)
下面是乙個測試:
int main(int argc, char **argv)
nfree(5);
nfree(0);
nfree(7);
for (i = 0; i < num+1; i++)
printf("nendn");
}
這個**用在何處呢?前面說過,用在資源可以表示為連續id的場合,這種場合何在?在《編寫乙個unix檔案系統》中,我說那個空閒i節點以及空閒塊的分配演算法不好,而上述的方法就可以用,效果比較好,也就是說,將一點點的工作施放於每次分配/釋放的時候,就可以避免在某個時間點做大量的積攢下來的繁重的工作。這個演算法省去了遍歷操作,代價就是占用了一點連續的位址空間。
折半查詢 適用於順序陣列
折半查詢的思路 在順序陣列中,找到初始值 最小值 中間值,最大值,分別以low,mid,high表示。然後進行迴圈查詢,例如圖 low 1,high 16,mid low high 2 如果key值剛好等於中間值mid,則返回中間值。如果所求值key比中間值大,則在mid與high之間在進行第二次查...
適用於python的 vimrc檔案
根據我的需求做了一些小的改動。file vimrc date 2009 09 22 author gashero note 配置乙份簡單的vim配置檔案 set nocompatible 非相容模式 syntax on 開啟語法高亮 set background dark 背景色 color des...
適用於終端互動的外掛程式JQuery Terminal
適用 並引入進去,這裡的外掛程式是基於jquery的,所以也要引入jquery.js,這裡我就不展示出來了。以上檔案都可以從官網能拿到。1,引入成功之後,要在頁面寫入乙個節點 2,我這裡用的是websocket做的互動 scope.getteminal function socket.onmessa...