Skip to content

Commit b5d47c8

Browse files
authored
Merge pull request #42 from baekrang256/master
Use binary search for searching extent
2 parents f46dadb + 71f7340 commit b5d47c8

File tree

1 file changed

+60
-10
lines changed

1 file changed

+60
-10
lines changed

extent.c

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,69 @@
66
/* Search for the extent containing the target block.
77
* Returns the first unused file index if not found.
88
* Returns -1 if the target block is out of range.
9-
* TODO: Implement binary search for efficiency.
9+
* Binary search is used for efficiency.
1010
*/
1111
uint32_t simplefs_ext_search(struct simplefs_file_ei_block *index,
1212
uint32_t iblock)
1313
{
14-
uint32_t i;
15-
for (i = 0; i < SIMPLEFS_MAX_EXTENTS; i++) {
16-
uint32_t block = index->extents[i].ee_block;
17-
uint32_t len = index->extents[i].ee_len;
18-
if (index->extents[i].ee_start == 0 ||
19-
(iblock >= block && iblock < block + len))
20-
return i;
14+
/* first, find the first unused file index with binary search.
15+
* It'll be our right boundary for actual binary search
16+
* and return value when file index is not found.
17+
*/
18+
uint32_t start = 0;
19+
uint32_t end = SIMPLEFS_MAX_EXTENTS - 1;
20+
uint32_t boundary;
21+
uint32_t end_block;
22+
uint32_t end_len;
23+
24+
while (start < end) {
25+
uint32_t mid = start + (end - start) / 2;
26+
if (index->extents[mid].ee_start == 0) {
27+
end = mid;
28+
} else {
29+
start = mid + 1;
30+
}
31+
}
32+
33+
if (index->extents[end].ee_start == 0) {
34+
boundary = end;
35+
} else {
36+
/* File index full */
37+
boundary = end + 1;
38+
}
39+
40+
if (boundary == 0) {
41+
/* No used file index */
42+
return boundary;
43+
}
44+
45+
/* try finding target block using binary search */
46+
start = 0;
47+
end = boundary - 1;
48+
while (start < end) {
49+
uint32_t mid = start + (end - start) / 2;
50+
uint32_t block = index->extents[mid].ee_block;
51+
uint32_t len = index->extents[mid].ee_len;
52+
if (iblock >= block && iblock < block + len) {
53+
/* found before search finished */
54+
return mid;
55+
}
56+
if (iblock < block) {
57+
end = mid;
58+
} else {
59+
start = mid + 1;
60+
}
2161
}
2262

23-
return -1;
24-
}
63+
/* return 'end' if it directs to valid block
64+
* return 'boundary' if index is not found
65+
* and eiblock has remaining space */
66+
end_block = index->extents[end].ee_block;
67+
end_len = index->extents[end].ee_len;
68+
if (iblock >= end_block && iblock < end_len) {
69+
return end;
70+
} else if (boundary < SIMPLEFS_MAX_EXTENTS) {
71+
return boundary;
72+
}
73+
return boundary;
74+
}

0 commit comments

Comments
 (0)