9. What about memory use?
public class WeakReference Allows cache values to be
{ garbage-collected if they’re not
being referenced anywhere else.
private var dic:Dictionary;
public function WeakReference(obj:*)
{
dic = new Dictionary(true); Text
dic[obj] = 1;
}
public function getValue():* {
for (var item:* in dic) {
return item;
}
return null;
}
}
9
10. The Cache
How do we add an entity to the cache?
public class EntityCache
{
public function updateEntity(entity:BaseVO, ...):BaseVO
{
//...
}
}
10
11. Recurse through properties
Adding a user to the cache also adds its address.
UserVO
id: 1
firstname: “Zachary”
lastname: “Pinter” EntityCache
address: 1: UserVO
AddressVO 2: AddressVO
id: 2
line1: “4444 W 44th Ave”
city: “Denver”
state: “CO”
11
12. Recurse through properties
Arrays behave the same way
UserVO
id: 1
firstname: “Zachary”
lastname: “Pinter”
addresses: [ EntityCache
AddressVO
1: UserVO
id: 2
label: “home” 2: AddressVO
line1: “4444 W 44th Ave” 3: AddressVO
city: “Denver”
state: “CO”
AddressVO
id: 3
label: “work”
line1: “5555 W 55th Ave”
city: “Denver”
state: “CO”]
12
13. Finding an object’s properties
Spring Actionscript (formally Prana)
http://www.pranaframework.org/
var type:Type = Type.forName(classname);
for each (var accessor:Accessor in type.accessors) {
if (accessor.isStatic == false && accessor.access.name == quot;readwritequot;) {
result.push(accessor.name);
}
}
return result;
13
14. Finding an object’s properties
Source generator
public class UserVO extends BaseVO {
public var username : String;
public var firstname : String;
public var lastname : String;
public var address : AddressVO;
override public function getProperties():Array {
return super.getProperties().concat(quot;usernamequot;,quot;firstnamequot;,quot;lastnamequot;,quot;addressquot;);
}
}
14
15. Updating the cache
What if the entity is already in the cache?
EntityCache EntityCache.updateEntity(
1: UserVO(instance A) UserVO(instance B)
id: 1 id: 1
firstname: “Robert” firstname: “Bob”
lastname: “Smith” lastname: “Smith”
)
Copy the properties from
instance B into instance A
EntityCache
Leave instance A in the
1: UserVO(instance A)
cache
id: 1
firstname: “Bob” Discard instance B
lastname: “Smith”
15
16. Updating the cache
What about arrays?
EntityCache
UserVO
id: 1
firstname: “Zachary”
lastname: “Pinter” EntityCache.updateEntity(
addresses: [ AddressVO(instance B)
AddressVO(instance A)
id: 2
id: 2
label: “home” label: “home”
line1: “4444 W 44th Ave” line1: “3333 W 33rd Ave”
city: “Denver” city: “Denver”
state: “CO” state: “CO”
AddressVO )
id: 3
label: “work”
line1: “5555 W 55th Ave”
city: “Denver”
state: “CO”]
16
17. Updating the cache
What about arrays?
UserVO
id: 1 Since we update the existing instance,
firstname: “Zachary” all references to it will see the update.
lastname: “Pinter”
addresses: [
AddressVO(instance A)
id: 2
label: “home”
line1: “3333 W 33rd Ave”
city: “Denver”
state: “CO”
AddressVO
id: 3
label: “work”
line1: “5555 W 55th Ave”
city: “Denver”
state: “CO”]
17
18. Updating the Cache
The flip side
UserVO
EntityCache id: 5
AddressVO(instance A) firstname: “Zachary”
lastname: “Pinter”
id: 2
addresses: [
label: “home” AddressVO(instance B)
line1: “5555 W 55th Ave” id: 2
city: “Denver” label: “home”
state: “CO” line1: “6666 W 66th Ave”
city: “Denver”
state: “CO”
Your cache already has an
AddressVO
AddressVO with id 2 in it, and you
id: 3
add a new UserVO to the cache that
label: “work”
references an updated instance of the
line1: “5555 W 55th Ave”
AddressVO
city: “Denver”
state: “CO”]
18
19. Updating the Cache
UserVO
EntityCache id: 5
AddressVO(instance A) firstname: “Zachary”
lastname: “Pinter”
id: 2
addresses: [
label: “home” AddressVO(instance A)
line1: “6666 W 66th Ave” id: 2
city: “Denver” label: “home”
state: “CO” line1: “6666 W 66th Ave”
city: “Denver”
state: “CO”
The AddressVO in the cache is AddressVO
updated and the AddressVO in id: 3
UserVO.addresses is replaced with label: “work”
the instance from the cache. line1: “5555 W 55th Ave”
city: “Denver”
state: “CO”]
19
20. Updating the Cache
Code looks something like this...
if (obj is Array) {
var arr:Array = obj as Array;
for (var i:int=0;i<arr.length;i++) {
if (arr[i] is BaseVO) {
var res:BaseVO = updateEntity(arr[i] as BaseVO,...);
if (res != null) arr[i] = res;
}
}
}
20
21. Updating the Cache
ArrayCollection’s are slightly trickier
if (obj is ArrayCollection) {
var ac:ArrayCollection = obj as ArrayCollection;
ac.disableAutoUpdate();
for (i=0;i<ac.length;i++) {
if (ac.getItemAt(i) is BaseVO) {
var res:BaseVO = updateEntity(ac.getItemAt(i) as BaseVO,...);
if (res != null) {
ac.setItemAt(res,i);
}
}
}
ac.enableAutoUpdate();
}
21
23. The Cache
How do we get an entity?
What happens if we ask for an entity that isn’t in the cache?
public class EntityCache
{
public function getEntity(id:String):EntityWrapper
{
//...
}
}
23
24. EntityWrapper
[Bindable]
When requesting an entity, a
public class EntityWrapper wrapper object is returned.
{
public var entityId:String; If that object is in the cache,
public var entity:BaseVO; EntityWrapper.entity will have a
value.
public function EntityWrapper(id:String)
{ If the object is not in the cache,
entityId = id;
} EntityWrapper.entity will be null
and a call to fetch the entity will
} be queued.
24
25. Using the Cache
userWrapper = cache.getEntity(userid.text);
<mx:Label text=quot;Username: {userWrapper.entity.username}quot;/>
25
26. Using the Cache - List Renderers
Benefits
‣ Faster initial query since you’re only grabbing the id’s
‣ Rows are lazy-fetched as you scroll
Drawbacks
‣ Sorting has to be handled by the server
26
27. Using the Cache - List Renderers
What’s the code for the item renderer look like?
override public function set data(val:Object):void
{
if(val != data){
if (!val) {
wrapper = null;
} else {
wrapper = cache.getEntity(val);
}
super.data = val;
}
}
27
30. Dictionary Keys
Only one cache, need to prevent collisions
Some Options:
‣ Globally unique sequence across all tables (UserVO with id 1, AddressVO with id 2)
‣ UUID’s (great for generating new id’s flex-side)
‣ Combine type with id (“UserVO-1”, “AddressVO-1”)
30