1 //----------------------------------------------------------------------
2 // This software is part of the OpenBeOS distribution and is covered
4 //---------------------------------------------------------------------
11 #include <disk_device_manager.h>
12 #include <PartitioningInfo.h>
15 #include <ddm_userland_interface_defs.h>
23 # define TRACE(x) printf x
30 BPartitioningInfo::BPartitioningInfo()
41 BPartitioningInfo::~BPartitioningInfo()
49 BPartitioningInfo::SetTo(off_t offset
, off_t size
)
51 TRACE(("%p - BPartitioningInfo::SetTo(offset = %lld, size = %lld)\n", this, offset
, size
));
57 fSpaces
= new(nothrow
) partitionable_space_data
[1];
62 fSpaces
[0].offset
= offset
;
63 fSpaces
[0].size
= size
;
77 BPartitioningInfo::Unset()
87 // ExcludeOccupiedSpace
89 BPartitioningInfo::ExcludeOccupiedSpace(off_t offset
, off_t size
)
94 TRACE(("%p - BPartitioningInfo::ExcludeOccupiedSpace(offset = %lld, "
95 "size = %lld)\n", this, offset
, size
));
98 int32 rightIndex
= -1;
99 for (int32 i
= 0; i
< fCount
; i
++) {
101 && offset
< fSpaces
[i
].offset
+ fSpaces
[i
].size
) {
105 if (fSpaces
[i
].offset
< offset
+ size
)
109 TRACE((" leftIndex = %ld, rightIndex = %ld\n", leftIndex
, rightIndex
));
111 // If there's no intersection with any free space, we're done.
112 if (leftIndex
== -1 || rightIndex
== -1 || leftIndex
> rightIndex
)
115 partitionable_space_data
& leftSpace
= fSpaces
[leftIndex
];
116 partitionable_space_data
& rightSpace
= fSpaces
[rightIndex
];
118 off_t rightSpaceEnd
= rightSpace
.offset
+ rightSpace
.size
;
120 // special case: split a single space in two
121 if (leftIndex
== rightIndex
&& leftSpace
.offset
< offset
122 && rightSpaceEnd
> offset
+ size
) {
124 TRACE((" splitting space at %ld\n", leftIndex
));
126 // add a space after this one
127 status_t error
= _InsertSpaces(leftIndex
+ 1, 1);
131 // IMPORTANT: after calling _InsertSpace(), one can not
132 // use the partitionable_space_data references "leftSpace"
133 // and "rightSpace" anymore (declared above)!
135 partitionable_space_data
& space
= fSpaces
[leftIndex
];
136 partitionable_space_data
& newSpace
= fSpaces
[leftIndex
+ 1];
138 space
.size
= offset
- space
.offset
;
140 newSpace
.offset
= offset
+ size
;
141 newSpace
.size
= rightSpaceEnd
- newSpace
.offset
;
149 // check whether the first affected space is eaten completely
150 int32 deleteFirst
= leftIndex
;
151 if (leftSpace
.offset
< offset
) {
152 leftSpace
.size
= offset
- leftSpace
.offset
;
154 TRACE((" left space remains, new size is %lld\n", leftSpace
.size
));
159 // check whether the last affected space is eaten completely
160 int32 deleteLast
= rightIndex
;
161 if (rightSpaceEnd
> offset
+ size
) {
162 rightSpace
.offset
= offset
+ size
;
163 rightSpace
.size
= rightSpaceEnd
- rightSpace
.offset
;
165 TRACE((" right space remains, new offset = %lld, size = %lld\n",
166 rightSpace
.offset
, rightSpace
.size
));
171 // remove all spaces that are completely eaten
172 if (deleteFirst
<= deleteLast
)
173 _RemoveSpaces(deleteFirst
, deleteLast
- deleteFirst
+ 1);
184 BPartitioningInfo::PartitionID() const
190 // GetPartitionableSpaceAt
192 BPartitioningInfo::GetPartitionableSpaceAt(int32 index
, off_t
* offset
,
197 if (!offset
|| !size
)
199 if (index
< 0 || index
>= fCount
)
201 *offset
= fSpaces
[index
].offset
;
202 *size
= fSpaces
[index
].size
;
207 // CountPartitionableSpaces
209 BPartitioningInfo::CountPartitionableSpaces() const
217 BPartitioningInfo::PrintToStream() const
220 printf("BPartitioningInfo is not initialized\n");
223 printf("BPartitioningInfo has %" B_PRId32
" spaces:\n", fCount
);
224 for (int32 i
= 0; i
< fCount
; i
++) {
225 printf(" space at %" B_PRId32
": offset = %" B_PRId64
", size = %"
226 B_PRId64
"\n", i
, fSpaces
[i
].offset
, fSpaces
[i
].size
);
236 BPartitioningInfo::_InsertSpaces(int32 index
, int32 count
)
238 if (index
<= 0 || index
> fCount
|| count
<= 0)
241 // If the capacity is sufficient, we just need to copy the spaces to create
243 if (fCount
+ count
<= fCapacity
) {
244 memmove(fSpaces
+ index
+ count
, fSpaces
+ index
,
245 (fCount
- index
) * sizeof(partitionable_space_data
));
251 int32 capacity
= (fCount
+ count
) * 2;
252 // add a bit room for further resizing
254 partitionable_space_data
* spaces
255 = new(nothrow
) partitionable_space_data
[capacity
];
260 memcpy(spaces
, fSpaces
, index
* sizeof(partitionable_space_data
));
261 memcpy(spaces
+ index
+ count
, fSpaces
+ index
,
262 (fCount
- index
) * sizeof(partitionable_space_data
));
266 fCapacity
= capacity
;
275 BPartitioningInfo::_RemoveSpaces(int32 index
, int32 count
)
277 if (index
< 0 || count
<= 0 || index
+ count
> fCount
)
280 if (count
< fCount
) {
281 int32 endIndex
= index
+ count
;
282 memmove(fSpaces
+ index
, fSpaces
+ endIndex
,
283 (fCount
- endIndex
) * sizeof(partitionable_space_data
));