1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 cr
.define('media', function() {
9 * This class represents a file cached by net.
11 function CacheEntry() {
12 this.read_
= new media
.DisjointRangeSet
;
13 this.written_
= new media
.DisjointRangeSet
;
14 this.available_
= new media
.DisjointRangeSet
;
16 // Set to true when we know the entry is sparse.
21 // The <details> element representing this CacheEntry.
22 this.details_
= document
.createElement('details');
23 this.details_
.className
= 'cache-entry';
24 this.details_
.open
= false;
26 // The <details> summary line. It contains a chart of requested file ranges
27 // and the url if we know it.
28 var summary
= document
.createElement('summary');
30 this.summaryText_
= document
.createTextNode('');
31 summary
.appendChild(this.summaryText_
);
33 summary
.appendChild(document
.createTextNode(' '));
35 // Controls to modify this CacheEntry.
36 var controls
= document
.createElement('span');
37 controls
.className
= 'cache-entry-controls';
38 summary
.appendChild(controls
);
39 summary
.appendChild(document
.createElement('br'));
41 // A link to clear recorded data from this CacheEntry.
42 var clearControl
= document
.createElement('a');
43 clearControl
.href
= 'javascript:void(0)';
44 clearControl
.onclick
= this.clear
.bind(this);
45 clearControl
.textContent
= '(clear entry)';
46 controls
.appendChild(clearControl
);
48 this.details_
.appendChild(summary
);
50 // The canvas for drawing cache writes.
51 this.writeCanvas
= document
.createElement('canvas');
52 this.writeCanvas
.width
= media
.BAR_WIDTH
;
53 this.writeCanvas
.height
= media
.BAR_HEIGHT
;
54 this.details_
.appendChild(this.writeCanvas
);
56 // The canvas for drawing cache reads.
57 this.readCanvas
= document
.createElement('canvas');
58 this.readCanvas
.width
= media
.BAR_WIDTH
;
59 this.readCanvas
.height
= media
.BAR_HEIGHT
;
60 this.details_
.appendChild(this.readCanvas
);
62 // A tabular representation of the data in the above canvas.
63 this.detailTable_
= document
.createElement('table');
64 this.detailTable_
.className
= 'cache-table';
65 this.details_
.appendChild(this.detailTable_
);
68 CacheEntry
.prototype = {
70 * Mark a range of bytes as read from the cache.
71 * @param {int} start The first byte read.
72 * @param {int} length The number of bytes read.
74 readBytes: function(start
, length
) {
75 start
= parseInt(start
);
76 length
= parseInt(length
);
77 this.read_
.add(start
, start
+ length
);
78 this.available_
.add(start
, start
+ length
);
83 * Mark a range of bytes as written to the cache.
84 * @param {int} start The first byte written.
85 * @param {int} length The number of bytes written.
87 writeBytes: function(start
, length
) {
88 start
= parseInt(start
);
89 length
= parseInt(length
);
90 this.written_
.add(start
, start
+ length
);
91 this.available_
.add(start
, start
+ length
);
96 * Merge this CacheEntry with another, merging recorded ranges and flags.
97 * @param {CacheEntry} other The CacheEntry to merge into this one.
99 merge: function(other
) {
100 this.read_
.merge(other
.read_
);
101 this.written_
.merge(other
.written_
);
102 this.available_
.merge(other
.available_
);
103 this.sparse
= this.sparse
|| other
.sparse
;
104 this.key
= this.key
|| other
.key
;
105 this.size
= this.size
|| other
.size
;
109 * Clear all recorded ranges from this CacheEntry and redraw this.details_.
112 this.read_
= new media
.DisjointRangeSet
;
113 this.written_
= new media
.DisjointRangeSet
;
114 this.available_
= new media
.DisjointRangeSet
;
115 this.generateDetails();
119 * Helper for drawCacheReadsToCanvas() and drawCacheWritesToCanvas().
121 * Accepts the entries to draw, a canvas fill style, and the canvas to
124 drawCacheEntriesToCanvas: function(entries
, fillStyle
, canvas
) {
125 // Don't bother drawing anything if we don't know the total size.
130 var width
= canvas
.width
;
131 var height
= canvas
.height
;
132 var context
= canvas
.getContext('2d');
133 var fileSize
= this.size
;
135 context
.fillStyle
= '#aaa';
136 context
.fillRect(0, 0, width
, height
);
138 function drawRange(start
, end
) {
139 var left
= start
/ fileSize
* width
;
140 var right
= end
/ fileSize
* width
;
141 context
.fillRect(left
, 0, right
- left
, height
);
144 context
.fillStyle
= fillStyle
;
145 entries
.map(function(start
, end
) {
146 drawRange(start
, end
);
151 * Draw cache writes to the given canvas.
153 * It should consist of a horizontal bar with highlighted sections to
154 * represent which parts of a file have been written to the cache.
156 * e.g. |xxxxxx----------x|
158 drawCacheWritesToCanvas: function(canvas
) {
159 this.drawCacheEntriesToCanvas(this.written_
, '#00a', canvas
);
163 * Draw cache reads to the given canvas.
165 * It should consist of a horizontal bar with highlighted sections to
166 * represent which parts of a file have been read from the cache.
168 * e.g. |xxxxxx----------x|
170 drawCacheReadsToCanvas: function(canvas
) {
171 this.drawCacheEntriesToCanvas(this.read_
, '#0a0', canvas
);
175 * Update this.details_ to contain everything we currently know about
178 generateDetails: function() {
179 function makeElement(tag
, content
) {
180 var toReturn
= document
.createElement(tag
);
181 toReturn
.textContent
= content
;
185 this.details_
.id
= this.key
;
186 this.summaryText_
.textContent
= this.key
|| 'Unknown File';
188 this.detailTable_
.textContent
= '';
189 var header
= document
.createElement('thead');
190 var footer
= document
.createElement('tfoot');
191 var body
= document
.createElement('tbody');
192 this.detailTable_
.appendChild(header
);
193 this.detailTable_
.appendChild(footer
);
194 this.detailTable_
.appendChild(body
);
196 var headerRow
= document
.createElement('tr');
197 headerRow
.appendChild(makeElement('th', 'Read From Cache'));
198 headerRow
.appendChild(makeElement('th', 'Written To Cache'));
199 header
.appendChild(headerRow
);
201 var footerRow
= document
.createElement('tr');
202 var footerCell
= document
.createElement('td');
203 footerCell
.textContent
= 'Out of ' + (this.size
|| 'unkown size');
204 footerCell
.setAttribute('colspan', 2);
205 footerRow
.appendChild(footerCell
);
206 footer
.appendChild(footerRow
);
208 var read
= this.read_
.map(function(start
, end
) {
209 return start
+ ' - ' + end
;
211 var written
= this.written_
.map(function(start
, end
) {
212 return start
+ ' - ' + end
;
215 var length
= Math
.max(read
.length
, written
.length
);
216 for (var i
= 0; i
< length
; i
++) {
217 var row
= document
.createElement('tr');
218 row
.appendChild(makeElement('td', read
[i
] || ''));
219 row
.appendChild(makeElement('td', written
[i
] || ''));
220 body
.appendChild(row
);
223 this.drawCacheWritesToCanvas(this.writeCanvas
);
224 this.drawCacheReadsToCanvas(this.readCanvas
);
228 * Render this CacheEntry as a <li>.
229 * @return {HTMLElement} A <li> representing this CacheEntry.
231 toListItem: function() {
232 this.generateDetails();
234 var result
= document
.createElement('li');
235 result
.appendChild(this.details_
);
241 CacheEntry
: CacheEntry