allocate.js
1.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
const { assign } = require("./tools");
function searchBlock(state, process) {
let candidates = state
.map((block, key) => assign(block, { key }))
.filter(block => block.id == -1 && block.size >= process.size);
candidates.sort((blockX, blockY) => {
const x = blockY.size;
const y = blockY.size;
if (x < y) return -1;
else if (x > y) return 1;
else return 0;
});
return candidates.length != 0 ? candidates[0].key : -1;
}
const getCapacity = state =>
state
.filter(block => block.id == -1)
.reduce((capacity, block) => capacity + block.size, 0);
function insert(state, process, target) {
const bound = target.from + process.size;
return target.size == process.size
? [assign(target, { id: process.id })]
: [
assign(target, { id: process.id, size: process.size }),
assign(target, { size: target.size - process.size })
];
}
function compact(state) {
const size = getCapacity(state);
return [...state.filter(block => block.id != -1), { id: -1, size }];
}
function allocate(state, process) {
const capacity = getCapacity(state);
if (capacity < process.size) {
throw new Error("OUT OF MEMORY");
}
let idx = searchBlock(state, process);
if (idx == -1) {
state = compact(state);
idx = searchBlock(state, process);
}
const target = state[idx];
const nextState = [
...state.slice(0, idx),
...insert(state, process, target),
...state.slice(idx + 1)
];
const offset = idx;
return nextState;
}
module.exports = allocate;