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 */
1111uint32_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