Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
91bcec82
authored
May 22, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Support an up-front block allocation in DefaultAllocator.
parent
79d557dd
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
78 additions
and
15 deletions
library/src/main/java/com/google/android/exoplayer/upstream/DefaultAllocator.java
library/src/main/java/com/google/android/exoplayer/upstream/DefaultAllocator.java
View file @
91bcec82
...
@@ -25,41 +25,72 @@ import java.util.Arrays;
...
@@ -25,41 +25,72 @@ import java.util.Arrays;
*/
*/
public
final
class
DefaultAllocator
implements
Allocator
{
public
final
class
DefaultAllocator
implements
Allocator
{
private
static
final
int
INITIAL_RECYCLED_ALLOCATION
_CAPACITY
=
100
;
private
static
final
int
AVAILABLE_EXTRA
_CAPACITY
=
100
;
private
final
int
individualAllocationSize
;
private
final
int
individualAllocationSize
;
private
final
byte
[]
initialAllocationBlock
;
private
int
allocatedCount
;
private
int
allocatedCount
;
private
int
recycled
Count
;
private
int
available
Count
;
private
Allocation
[]
recycled
Allocations
;
private
Allocation
[]
available
Allocations
;
/**
/**
* Constructs an empty pool.
* Constructs an
initially
empty pool.
*
*
* @param individualAllocationSize The length of each individual allocation.
* @param individualAllocationSize The length of each individual allocation.
*/
*/
public
DefaultAllocator
(
int
individualAllocationSize
)
{
public
DefaultAllocator
(
int
individualAllocationSize
)
{
this
(
individualAllocationSize
,
0
);
}
/**
* Constructs a pool with some {@link Allocation}s created up front.
* <p>
* Note: Initial {@link Allocation}s will never be discarded by {@link #trim(int)}.
*
* @param individualAllocationSize The length of each individual allocation.
* @param initialAllocationCount The number of allocations to create up front.
*/
public
DefaultAllocator
(
int
individualAllocationSize
,
int
initialAllocationCount
)
{
Assertions
.
checkArgument
(
individualAllocationSize
>
0
);
Assertions
.
checkArgument
(
individualAllocationSize
>
0
);
Assertions
.
checkArgument
(
initialAllocationCount
>=
0
);
this
.
individualAllocationSize
=
individualAllocationSize
;
this
.
individualAllocationSize
=
individualAllocationSize
;
this
.
recycledAllocations
=
new
Allocation
[
INITIAL_RECYCLED_ALLOCATION_CAPACITY
];
this
.
availableCount
=
initialAllocationCount
;
this
.
availableAllocations
=
new
Allocation
[
initialAllocationCount
+
AVAILABLE_EXTRA_CAPACITY
];
if
(
initialAllocationCount
>
0
)
{
initialAllocationBlock
=
new
byte
[
initialAllocationCount
*
individualAllocationSize
];
for
(
int
i
=
0
;
i
<
initialAllocationCount
;
i
++)
{
int
allocationOffset
=
i
*
individualAllocationSize
;
availableAllocations
[
i
]
=
new
Allocation
(
initialAllocationBlock
,
allocationOffset
);
}
}
else
{
initialAllocationBlock
=
null
;
}
}
}
@Override
@Override
public
synchronized
Allocation
allocate
()
{
public
synchronized
Allocation
allocate
()
{
allocatedCount
++;
allocatedCount
++;
return
recycledCount
>
0
?
recycledAllocations
[--
recycledCount
]
Allocation
allocation
;
:
new
Allocation
(
new
byte
[
individualAllocationSize
],
0
);
if
(
availableCount
>
0
)
{
allocation
=
availableAllocations
[--
availableCount
];
availableAllocations
[
availableCount
]
=
null
;
}
else
{
allocation
=
new
Allocation
(
new
byte
[
individualAllocationSize
],
0
);
}
return
allocation
;
}
}
@Override
@Override
public
synchronized
void
release
(
Allocation
allocation
)
{
public
synchronized
void
release
(
Allocation
allocation
)
{
// Weak sanity check that the allocation probably originated from this pool.
// Weak sanity check that the allocation probably originated from this pool.
Assertions
.
checkArgument
(
allocation
.
data
.
length
==
individualAllocationSize
);
Assertions
.
checkArgument
(
allocation
.
data
==
initialAllocationBlock
||
allocation
.
data
.
length
==
individualAllocationSize
);
allocatedCount
--;
allocatedCount
--;
if
(
recycledCount
==
recycled
Allocations
.
length
)
{
if
(
availableCount
==
available
Allocations
.
length
)
{
recycledAllocations
=
Arrays
.
copyOf
(
recycledAllocations
,
recycled
Allocations
.
length
*
2
);
availableAllocations
=
Arrays
.
copyOf
(
availableAllocations
,
available
Allocations
.
length
*
2
);
}
}
recycledAllocations
[
recycled
Count
++]
=
allocation
;
availableAllocations
[
available
Count
++]
=
allocation
;
// Wake up threads waiting for the allocated size to drop.
// Wake up threads waiting for the allocated size to drop.
notifyAll
();
notifyAll
();
}
}
...
@@ -67,11 +98,43 @@ public final class DefaultAllocator implements Allocator {
...
@@ -67,11 +98,43 @@ public final class DefaultAllocator implements Allocator {
@Override
@Override
public
synchronized
void
trim
(
int
targetSize
)
{
public
synchronized
void
trim
(
int
targetSize
)
{
int
targetAllocationCount
=
Util
.
ceilDivide
(
targetSize
,
individualAllocationSize
);
int
targetAllocationCount
=
Util
.
ceilDivide
(
targetSize
,
individualAllocationSize
);
int
target
RecycledAllocation
Count
=
Math
.
max
(
0
,
targetAllocationCount
-
allocatedCount
);
int
target
Available
Count
=
Math
.
max
(
0
,
targetAllocationCount
-
allocatedCount
);
if
(
target
RecycledAllocationCount
<
recycled
Count
)
{
if
(
target
AvailableCount
>=
available
Count
)
{
Arrays
.
fill
(
recycledAllocations
,
targetRecycledAllocationCount
,
recycledCount
,
null
);
// We're already at or below the target.
re
cycledCount
=
targetRecycledAllocationCount
;
re
turn
;
}
}
if
(
initialAllocationBlock
!=
null
)
{
// Some allocations are backed by an initial block. We need to make sure that we hold onto all
// such allocations. Re-order the available allocations so that the ones backed by the initial
// block come first.
int
lowIndex
=
0
;
int
highIndex
=
availableCount
-
1
;
while
(
lowIndex
<=
highIndex
)
{
Allocation
lowAllocation
=
availableAllocations
[
lowIndex
];
if
(
lowAllocation
.
data
==
initialAllocationBlock
)
{
lowIndex
++;
}
else
{
Allocation
highAllocation
=
availableAllocations
[
lowIndex
];
if
(
highAllocation
.
data
!=
initialAllocationBlock
)
{
highIndex
--;
}
else
{
availableAllocations
[
lowIndex
++]
=
highAllocation
;
availableAllocations
[
highIndex
--]
=
lowAllocation
;
}
}
}
// lowIndex is the index of the first allocation not backed by an initial block.
targetAvailableCount
=
Math
.
max
(
targetAvailableCount
,
lowIndex
);
if
(
targetAvailableCount
>=
availableCount
)
{
// We're already at or below the target.
return
;
}
}
// Discard allocations beyond the target.
Arrays
.
fill
(
availableAllocations
,
targetAvailableCount
,
availableCount
,
null
);
availableCount
=
targetAvailableCount
;
}
}
@Override
@Override
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment