Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
da88f1d0
Commit
da88f1d0
authored
Mar 23, 2016
by
Ian Hickson
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2828 from Hixie/lru
Replace use of LruMap with a pure LinkedHashMap
parents
924480fc
ea04c910
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
211 additions
and
11 deletions
+211
-11
image_cache.dart
packages/flutter/lib/src/services/image_cache.dart
+39
-10
pubspec.yaml
packages/flutter/pubspec.yaml
+0
-1
image_cache_resize_test.dart
packages/flutter/test/services/image_cache_resize_test.dart
+41
-0
image_cache_test.dart
packages/flutter/test/services/image_cache_test.dart
+83
-0
mocks_for_image_cache.dart
packages/flutter/test/services/mocks_for_image_cache.dart
+48
-0
No files found.
packages/flutter/lib/src/services/image_cache.dart
View file @
da88f1d0
...
...
@@ -3,10 +3,10 @@
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:collection'
;
import
'dart:ui'
show
hashValues
;
import
'package:mojo/mojo/url_response.mojom.dart'
;
import
'package:quiver/collection.dart'
;
import
'fetch.dart'
;
import
'image_decoder.dart'
;
...
...
@@ -25,6 +25,12 @@ import 'image_resource.dart';
/// share the same cache as all the other image loading codepaths that used the
/// [imageCache].
abstract
class
ImageProvider
{
// ignore: one_member_abstracts
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const
ImageProvider
();
/// Subclasses must implement this method by having it asynchronously return
/// an [ImageInfo] that represents the image provided by this [ImageProvider].
Future
<
ImageInfo
>
loadImage
();
/// Subclasses must implement the `==` operator so that the image cache can
...
...
@@ -88,22 +94,34 @@ const int _kDefaultSize = 1000;
class
ImageCache
{
ImageCache
.
_
();
final
L
ru
Map
<
ImageProvider
,
ImageResource
>
_cache
=
new
L
ruMap
<
ImageProvider
,
ImageResource
>(
maximumSize:
_kDefaultSize
);
final
L
inkedHash
Map
<
ImageProvider
,
ImageResource
>
_cache
=
new
L
inkedHashMap
<
ImageProvider
,
ImageResource
>(
);
/// Maximum number of entries to store in the cache.
///
/// Once this many entries have been cached, the least-recently-used entry is
/// evicted when adding a new entry.
int
get
maximumSize
=>
_cache
.
maximumSize
;
int
get
maximumSize
=>
_maximumSize
;
int
_maximumSize
=
_kDefaultSize
;
/// Changes the maximum cache size.
///
/// If the new size is smaller than the current number of elements, the
/// extraneous elements are evicted immediately. Setting this to zero and then
/// returning it to its original value will therefore immediately clear the
/// cache. However, doing this is not very efficient.
// (the quiver library does it one at a time rather than using clear())
void
set
maximumSize
(
int
value
)
{
_cache
.
maximumSize
=
value
;
}
/// cache.
void
set
maximumSize
(
int
value
)
{
assert
(
value
!=
null
);
assert
(
value
>=
0
);
if
(
value
==
maximumSize
)
return
;
_maximumSize
=
value
;
if
(
maximumSize
==
0
)
{
_cache
.
clear
();
}
else
{
while
(
_cache
.
length
>
maximumSize
)
_cache
.
remove
(
_cache
.
keys
.
first
);
}
}
/// Calls the [ImageProvider.loadImage] method on the given image provider, if
/// necessary, and returns an [ImageResource] that encapsulates a [Future] for
...
...
@@ -113,9 +131,20 @@ class ImageCache {
/// cache, then the [ImageResource] object is immediately usable and the
/// provider is not invoked.
ImageResource
loadProvider
(
ImageProvider
provider
)
{
return
_cache
.
putIfAbsent
(
provider
,
()
{
return
new
ImageResource
(
provider
.
loadImage
());
});
ImageResource
result
=
_cache
[
provider
];
if
(
result
!=
null
)
{
_cache
.
remove
(
provider
);
}
else
{
if
(
_cache
.
length
==
maximumSize
&&
maximumSize
>
0
)
_cache
.
remove
(
_cache
.
keys
.
first
);
result
=
new
ImageResource
(
provider
.
loadImage
());;
}
if
(
maximumSize
>
0
)
{
assert
(
_cache
.
length
<
maximumSize
);
_cache
[
provider
]
=
result
;
}
assert
(
_cache
.
length
<=
maximumSize
);
return
result
;
}
/// Fetches the given URL, associating it with the given scale.
...
...
packages/flutter/pubspec.yaml
View file @
da88f1d0
...
...
@@ -8,7 +8,6 @@ dependencies:
collection
:
'
>=1.4.0
<2.0.0'
intl
:
'
>=0.12.4+2
<0.13.0'
vector_math
:
'
>=1.4.5
<2.0.0'
quiver
:
'
>=0.21.4
<0.22.0'
sky_engine
:
path
:
../../bin/cache/pkg/sky_engine
...
...
packages/flutter/test/services/image_cache_resize_test.dart
0 → 100644
View file @
da88f1d0
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/services.dart'
;
import
'package:test/test.dart'
;
import
'mocks_for_image_cache.dart'
;
void
main
(
)
{
test
(
'Image cache resizing'
,
()
async
{
imageCache
.
maximumSize
=
2
;
TestImageInfo
a
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
1
)).
first
);
TestImageInfo
b
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
2
,
2
)).
first
);
TestImageInfo
c
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
3
,
3
)).
first
);
TestImageInfo
d
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
4
)).
first
);
expect
(
a
.
value
,
equals
(
1
));
expect
(
b
.
value
,
equals
(
2
));
expect
(
c
.
value
,
equals
(
3
));
expect
(
d
.
value
,
equals
(
4
));
imageCache
.
maximumSize
=
0
;
TestImageInfo
e
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
5
)).
first
);
expect
(
e
.
value
,
equals
(
5
));
TestImageInfo
f
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
6
)).
first
);
expect
(
f
.
value
,
equals
(
6
));
imageCache
.
maximumSize
=
3
;
TestImageInfo
g
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
7
)).
first
);
expect
(
g
.
value
,
equals
(
7
));
TestImageInfo
h
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
8
)).
first
);
expect
(
h
.
value
,
equals
(
7
));
});
}
packages/flutter/test/services/image_cache_test.dart
0 → 100644
View file @
da88f1d0
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/services.dart'
;
import
'package:test/test.dart'
;
import
'mocks_for_image_cache.dart'
;
void
main
(
)
{
test
(
'Image cache'
,
()
async
{
imageCache
.
maximumSize
=
3
;
TestImageInfo
a
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
1
)).
first
);
expect
(
a
.
value
,
equals
(
1
));
TestImageInfo
b
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
2
)).
first
);
expect
(
b
.
value
,
equals
(
1
));
TestImageInfo
c
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
3
)).
first
);
expect
(
c
.
value
,
equals
(
1
));
TestImageInfo
d
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
4
)).
first
);
expect
(
d
.
value
,
equals
(
1
));
TestImageInfo
e
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
5
)).
first
);
expect
(
e
.
value
,
equals
(
1
));
TestImageInfo
f
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
6
)).
first
);
expect
(
f
.
value
,
equals
(
1
));
expect
(
f
,
equals
(
a
));
// cache still only has one entry in it: 1(1)
TestImageInfo
g
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
2
,
7
)).
first
);
expect
(
g
.
value
,
equals
(
7
));
// cache has two entries in it: 1(1), 2(7)
TestImageInfo
h
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
8
)).
first
);
expect
(
h
.
value
,
equals
(
1
));
// cache still has two entries in it: 2(7), 1(1)
TestImageInfo
i
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
3
,
9
)).
first
);
expect
(
i
.
value
,
equals
(
9
));
// cache has three entries in it: 2(7), 1(1), 3(9)
TestImageInfo
j
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
10
)).
first
);
expect
(
j
.
value
,
equals
(
1
));
// cache still has three entries in it: 2(7), 3(9), 1(1)
TestImageInfo
k
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
4
,
11
)).
first
);
expect
(
k
.
value
,
equals
(
11
));
// cache has three entries: 3(9), 1(1), 4(11)
TestImageInfo
l
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
12
)).
first
);
expect
(
l
.
value
,
equals
(
1
));
// cache has three entries: 3(9), 4(11), 1(1)
TestImageInfo
m
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
2
,
13
)).
first
);
expect
(
m
.
value
,
equals
(
13
));
// cache has three entries: 4(11), 1(1), 2(13)
TestImageInfo
n
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
3
,
14
)).
first
);
expect
(
n
.
value
,
equals
(
14
));
// cache has three entries: 1(1), 2(13), 3(14)
TestImageInfo
o
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
4
,
15
)).
first
);
expect
(
o
.
value
,
equals
(
15
));
// cache has three entries: 2(13), 3(14), 4(15)
TestImageInfo
p
=
(
await
imageCache
.
loadProvider
(
new
TestProvider
(
1
,
16
)).
first
);
expect
(
p
.
value
,
equals
(
16
));
// cache has three entries: 3(14), 4(15), 1(16)
});
}
packages/flutter/test/services/mocks_for_image_cache.dart
0 → 100644
View file @
da88f1d0
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:ui'
as
ui
show
Image
;
import
'package:flutter/services.dart'
;
class
TestImageInfo
implements
ImageInfo
{
const
TestImageInfo
(
this
.
value
)
:
image
=
null
,
scale
=
null
;
@override
final
ui
.
Image
image
;
// ignored in test
@override
final
double
scale
;
// ignored in test
final
int
value
;
@override
String
toString
()
=>
'
$runtimeType
(
$value
)'
;
}
class
TestProvider
extends
ImageProvider
{
const
TestProvider
(
this
.
equalityValue
,
this
.
imageValue
);
final
int
imageValue
;
final
int
equalityValue
;
@override
Future
<
ImageInfo
>
loadImage
()
async
{
return
new
TestImageInfo
(
imageValue
);
}
@override
bool
operator
==(
dynamic
other
)
{
if
(
other
is
!
TestProvider
)
return
false
;
final
TestProvider
typedOther
=
other
;
return
equalityValue
==
typedOther
.
equalityValue
;
}
@override
int
get
hashCode
=>
equalityValue
.
hashCode
;
@override
String
toString
()
=>
'
$runtimeType
(
$equalityValue
,
$imageValue
)'
;
}
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