1/*
2 * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef BLOCK_ALLOCATOR_H
6#define BLOCK_ALLOCATOR_H
7
8
9#include <lock.h>
10
11
12struct Transaction;
13struct Volume;
14
15
16class BlockAllocator {
17public:
18								BlockAllocator(Volume* volume);
19								~BlockAllocator();
20
21			uint64				BaseBlock() const
22									{ return fAllocationGroupBlock; }
23			uint64				FreeBlocks() const	{ return fFreeBlocks; }
24
25			status_t			Init(uint64 blockBitmap, uint64 freeBlocks);
26			status_t			Initialize(Transaction& transaction);
27
28			status_t			Allocate(uint64 baseHint, uint64 count,
29									Transaction& transaction,
30									uint64& _allocatedBase,
31									uint64& _allocatedCount);
32			status_t			AllocateExactly(uint64 base,
33									uint64 count, Transaction& transaction);
34			status_t			Free(uint64 base, uint64 count,
35									Transaction& transaction);
36
37			void				ResetFreeBlocks(uint64 count);
38									// interface for Transaction only
39
40private:
41			status_t			_Allocate(uint64 base, uint64 searchEnd,
42									uint64 count, Transaction& transaction,
43									uint64* _allocatedBase,
44									uint64& _allocatedCount);
45			status_t			_AllocateInGroup(uint64 base, uint64 searchEnd,
46									uint32 count, Transaction& transaction,
47									uint64* _allocatedBase,
48									uint32& _allocatedCount);
49			status_t			_AllocateInBitmapBlock(uint64 base,
50									uint32 count, Transaction& transaction,
51									uint64* _allocatedBase,
52									uint32& _allocatedCount);
53
54			status_t			_Free(uint64 base, uint64 count,
55									Transaction& transaction);
56			status_t			_FreeInGroup(uint64 base, uint32 count,
57									Transaction& transaction);
58			status_t			_FreeInBitmapBlock(uint64 base, uint32 count,
59									Transaction& transaction);
60
61			status_t			_UpdateSuperBlock(Transaction& transaction);
62
63private:
64			mutex				fLock;
65			Volume*				fVolume;
66			uint64				fTotalBlocks;
67			uint64				fFreeBlocks;
68			uint64				fAllocationGroupBlock;
69			uint64				fAllocationGroupCount;
70			uint64				fBitmapBlock;
71			uint64				fBitmapBlockCount;
72};
73
74
75class AllocatedBlock {
76public:
77	AllocatedBlock(BlockAllocator* allocator, Transaction& transaction)
78		:
79		fAllocator(allocator),
80		fTransaction(transaction),
81		fIndex(0)
82	{
83	}
84
85	~AllocatedBlock()
86	{
87		if (fIndex > 0)
88			fAllocator->Free(fIndex, 1, fTransaction);
89	}
90
91	uint64 Index() const
92	{
93		return fIndex;
94	}
95
96	status_t Allocate(uint64 baseHint = 0)
97	{
98		uint64 allocatedBlocks;
99		status_t error = fAllocator->Allocate(0, 1, fTransaction, fIndex,
100			allocatedBlocks);
101		if (error != B_OK)
102			fIndex = 0;
103		return error;
104	}
105
106	uint64 Detach()
107	{
108		uint64 index = fIndex;
109		fIndex = 0;
110		return index;
111	}
112
113private:
114	BlockAllocator*	fAllocator;
115	Transaction&	fTransaction;
116	uint64			fIndex;
117};
118
119
120#endif	// BLOCK_ALLOCATOR_H
121