12
12
13
13
use digest:: Digest ;
14
14
use json;
15
- use json:: ToJson ;
16
15
use sha1:: Sha1 ;
17
16
use serialize:: { Encoder , Encodable , Decoder , Decodable } ;
18
17
use arc:: { Arc , RWArc } ;
19
18
use treemap:: TreeMap ;
19
+
20
20
use std:: cell:: Cell ;
21
21
use std:: comm:: { PortOne , oneshot} ;
22
22
use std:: either:: { Either , Left , Right } ;
23
- use std:: { io, os, task} ;
23
+ use std:: io;
24
+ use std:: run;
25
+ use std:: task;
24
26
25
27
/**
26
28
*
@@ -105,27 +107,11 @@ impl WorkKey {
105
107
}
106
108
}
107
109
108
- // FIXME #8883: The key should be a WorkKey and not a ~str.
109
- // This is working around some JSON weirdness.
110
- #[ deriving( Clone , Eq , Encodable , Decodable ) ]
111
- struct WorkMap ( TreeMap < ~str , KindMap > ) ;
112
-
113
110
#[ deriving( Clone , Eq , Encodable , Decodable ) ]
114
- struct KindMap ( TreeMap < ~ str , ~str > ) ;
111
+ struct WorkMap ( TreeMap < WorkKey , ~str > ) ;
115
112
116
113
impl WorkMap {
117
114
fn new ( ) -> WorkMap { WorkMap ( TreeMap :: new ( ) ) }
118
-
119
- fn insert_work_key ( & mut self , k : WorkKey , val : ~str ) {
120
- let WorkKey { kind, name } = k;
121
- match self . find_mut ( & name) {
122
- Some ( & KindMap ( ref mut m) ) => { m. insert ( kind, val) ; return ; }
123
- None => ( )
124
- }
125
- let mut new_map = TreeMap :: new ( ) ;
126
- new_map. insert ( kind, val) ;
127
- self . insert ( name, KindMap ( new_map) ) ;
128
- }
129
115
}
130
116
131
117
struct Database {
@@ -137,15 +123,11 @@ struct Database {
137
123
impl Database {
138
124
139
125
pub fn new ( p : Path ) -> Database {
140
- let mut rslt = Database {
126
+ Database {
141
127
db_filename : p,
142
128
db_cache : TreeMap :: new ( ) ,
143
129
db_dirty : false
144
- } ;
145
- if os:: path_exists ( & rslt. db_filename ) {
146
- rslt. load ( ) ;
147
130
}
148
- rslt
149
131
}
150
132
151
133
pub fn prepare ( & self ,
@@ -172,41 +154,6 @@ impl Database {
172
154
self . db_cache . insert ( k, v) ;
173
155
self . db_dirty = true
174
156
}
175
-
176
- // FIXME #4330: This should have &mut self and should set self.db_dirty to false.
177
- fn save ( & self ) {
178
- let f = io:: file_writer ( & self . db_filename , [ io:: Create , io:: Truncate ] ) . unwrap ( ) ;
179
- self . db_cache . to_json ( ) . to_pretty_writer ( f) ;
180
- }
181
-
182
- fn load ( & mut self ) {
183
- assert ! ( !self . db_dirty) ;
184
- assert ! ( os:: path_exists( & self . db_filename) ) ;
185
- let f = io:: file_reader ( & self . db_filename ) ;
186
- match f {
187
- Err ( e) => fail ! ( "Couldn't load workcache database %s: %s" ,
188
- self . db_filename. to_str( ) , e. to_str( ) ) ,
189
- Ok ( r) =>
190
- match json:: from_reader ( r) {
191
- Err ( e) => fail ! ( "Couldn't parse workcache database (from file %s): %s" ,
192
- self . db_filename. to_str( ) , e. to_str( ) ) ,
193
- Ok ( r) => {
194
- let mut decoder = json:: Decoder ( r) ;
195
- self . db_cache = Decodable :: decode ( & mut decoder) ;
196
- }
197
- }
198
- }
199
- }
200
- }
201
-
202
- // FIXME #4330: use &mut self here
203
- #[ unsafe_destructor]
204
- impl Drop for Database {
205
- fn drop ( & self ) {
206
- if self . db_dirty {
207
- self . save ( ) ;
208
- }
209
- }
210
157
}
211
158
212
159
struct Logger {
@@ -225,20 +172,12 @@ impl Logger {
225
172
}
226
173
}
227
174
228
- type FreshnessMap = TreeMap<~str,extern fn(&str,&str)->bool>;
229
-
230
175
#[deriving(Clone)]
231
176
struct Context {
232
177
db: RWArc<Database>,
233
178
logger: RWArc<Logger>,
234
179
cfg: Arc<json::Object>,
235
- /// Map from kinds (source, exe, url, etc.) to a freshness function.
236
- /// The freshness function takes a name (e.g. file path) and value
237
- /// (e.g. hash of file contents) and determines whether it's up-to-date.
238
- /// For example, in the file case, this would read the file off disk,
239
- /// hash it, and return the result of comparing the given hash and the
240
- /// read hash for equality.
241
- freshness: Arc<FreshnessMap>
180
+ freshness: Arc<TreeMap<~str,extern fn(&str,&str)->bool>>
242
181
}
243
182
244
183
struct Prep<'self> {
@@ -266,7 +205,6 @@ fn json_encode<T:Encodable<json::Encoder>>(t: &T) -> ~str {
266
205
267
206
// FIXME(#5121)
268
207
fn json_decode<T:Decodable<json::Decoder>>(s: &str) -> T {
269
- debug!(" json decoding: %s", s) ;
270
208
do io::with_str_reader(s) |rdr| {
271
209
let j = json::from_reader(rdr).unwrap();
272
210
let mut decoder = json::Decoder(j);
@@ -292,18 +230,11 @@ impl Context {
292
230
pub fn new(db: RWArc<Database>,
293
231
lg: RWArc<Logger>,
294
232
cfg: Arc<json::Object>) -> Context {
295
- Context :: new_with_freshness ( db, lg, cfg, Arc :: new ( TreeMap :: new ( ) ) )
296
- }
297
-
298
- pub fn new_with_freshness ( db : RWArc < Database > ,
299
- lg : RWArc < Logger > ,
300
- cfg : Arc < json:: Object > ,
301
- freshness : Arc < FreshnessMap > ) -> Context {
302
233
Context {
303
234
db: db,
304
235
logger: lg,
305
236
cfg: cfg,
306
- freshness : freshness
237
+ freshness: Arc::new(TreeMap::new())
307
238
}
308
239
}
309
240
@@ -318,36 +249,6 @@ impl Context {
318
249
319
250
}
320
251
321
- impl Exec {
322
- pub fn discover_input ( & mut self ,
323
- dependency_kind : & str ,
324
- dependency_name : & str ,
325
- dependency_val : & str ) {
326
- debug ! ( "Discovering input %s %s %s" , dependency_kind, dependency_name, dependency_val) ;
327
- self . discovered_inputs . insert_work_key ( WorkKey :: new ( dependency_kind, dependency_name) ,
328
- dependency_val. to_owned ( ) ) ;
329
- }
330
- pub fn discover_output ( & mut self ,
331
- dependency_kind : & str ,
332
- dependency_name : & str ,
333
- dependency_val : & str ) {
334
- debug ! ( "Discovering output %s %s %s" , dependency_kind, dependency_name, dependency_val) ;
335
- self . discovered_outputs . insert_work_key ( WorkKey :: new ( dependency_kind, dependency_name) ,
336
- dependency_val. to_owned ( ) ) ;
337
- }
338
-
339
- // returns pairs of (kind, name)
340
- pub fn lookup_discovered_inputs ( & self ) -> ~[ ( ~str , ~str ) ] {
341
- let mut rs = ~[ ] ;
342
- for ( k, v) in self . discovered_inputs . iter ( ) {
343
- for ( k1, _) in v. iter ( ) {
344
- rs. push ( ( k1. clone ( ) , k. clone ( ) ) ) ;
345
- }
346
- }
347
- rs
348
- }
349
- }
350
-
351
252
impl<'self> Prep<'self> {
352
253
fn new(ctxt: &'self Context, fn_name: &'self str) -> Prep<'self> {
353
254
Prep {
@@ -356,30 +257,18 @@ impl<'self> Prep<'self> {
356
257
declared_inputs: WorkMap::new()
357
258
}
358
259
}
359
-
360
- pub fn lookup_declared_inputs ( & self ) -> ~[ ~str ] {
361
- let mut rs = ~[ ] ;
362
- for ( _, v) in self . declared_inputs . iter ( ) {
363
- for ( inp, _) in v. iter ( ) {
364
- rs. push ( inp. clone ( ) ) ;
365
- }
366
- }
367
- rs
368
- }
369
260
}
370
261
371
262
impl<'self> Prep<'self> {
372
- pub fn declare_input ( & mut self , kind : & str , name : & str , val : & str ) {
373
- debug ! ( "Declaring input %s %s %s" , kind, name, val) ;
374
- self . declared_inputs . insert_work_key ( WorkKey :: new ( kind, name) ,
263
+ fn declare_input(&mut self, kind:&str, name:&str, val:&str) {
264
+ self.declared_inputs.insert(WorkKey::new(kind, name),
375
265
val.to_owned());
376
266
}
377
267
378
268
fn is_fresh(&self, cat: &str, kind: &str,
379
269
name: &str, val: &str) -> bool {
380
270
let k = kind.to_owned();
381
271
let f = self.ctxt.freshness.get().find(&k);
382
- debug ! ( "freshness for: %s/%s/%s/%s" , cat, kind, name, val)
383
272
let fresh = match f {
384
273
None => fail!(" missing freshness-function for ' %s' ", kind) ,
385
274
Some ( f) => ( * f) ( name, val)
@@ -397,31 +286,27 @@ impl<'self> Prep<'self> {
397
286
}
398
287
399
288
fn all_fresh ( & self , cat : & str , map : & WorkMap ) -> bool {
400
- for ( k_name, kindmap) in map. iter ( ) {
401
- for ( k_kind, v) in kindmap. iter ( ) {
402
- if ! self . is_fresh ( cat, * k_kind, * k_name, * v) {
403
- return false ;
289
+ for ( k, v) in map. iter ( ) {
290
+ if ! self . is_fresh ( cat, k. kind , k. name , * v) {
291
+ return false ;
404
292
}
405
- }
406
293
}
407
294
return true ;
408
295
}
409
296
410
- pub fn exec < T : Send +
297
+ fn exec < T : Send +
411
298
Encodable < json:: Encoder > +
412
299
Decodable < json:: Decoder > > (
413
- & ' self self , blk : ~fn ( & mut Exec ) -> T ) -> T {
300
+ & ' self self , blk : ~fn ( & Exec ) -> T ) -> T {
414
301
self . exec_work ( blk) . unwrap ( )
415
302
}
416
303
417
304
fn exec_work< T : Send +
418
305
Encodable < json:: Encoder > +
419
306
Decodable < json:: Decoder > > ( // FIXME(#5121)
420
- & ' self self , blk : ~fn ( & mut Exec ) -> T ) -> Work < ' self , T > {
307
+ & ' self self , blk : ~fn ( & Exec ) -> T ) -> Work < ' self , T > {
421
308
let mut bo = Some ( blk) ;
422
309
423
- debug ! ( "exec_work: looking up %s and %?" , self . fn_name,
424
- self . declared_inputs) ;
425
310
let cached = do self . ctxt . db . read |db| {
426
311
db. prepare ( self . fn_name , & self . declared_inputs )
427
312
} ;
@@ -431,26 +316,21 @@ impl<'self> Prep<'self> {
431
316
if self . all_fresh ( "declared input" , & self . declared_inputs ) &&
432
317
self . all_fresh ( "discovered input" , disc_in) &&
433
318
self . all_fresh ( "discovered output" , disc_out) => {
434
- debug ! ( "Cache hit!" ) ;
435
- debug ! ( "Trying to decode: %? / %? / %?" ,
436
- disc_in, disc_out, * res) ;
437
319
Left ( json_decode ( * res) )
438
320
}
439
321
440
322
_ => {
441
- debug ! ( "Cache miss!" ) ;
442
323
let ( port, chan) = oneshot ( ) ;
443
324
let blk = bo. take_unwrap ( ) ;
444
325
let chan = Cell :: new ( chan) ;
445
326
446
- // What happens if the task fails?
447
327
do task:: spawn {
448
- let mut exe = Exec {
328
+ let exe = Exec {
449
329
discovered_inputs : WorkMap :: new ( ) ,
450
330
discovered_outputs : WorkMap :: new ( ) ,
451
331
} ;
452
332
let chan = chan. take ( ) ;
453
- let v = blk ( & mut exe) ;
333
+ let v = blk ( & exe) ;
454
334
chan. send ( ( exe, v) ) ;
455
335
}
456
336
Right ( port)
@@ -491,23 +371,17 @@ impl<'self, T:Send +
491
371
}
492
372
493
373
494
- #[ test]
374
+ // #[test]
495
375
fn test( ) {
496
376
use std:: io:: WriterUtil ;
497
- use std :: { os, run} ;
498
377
499
378
let pth = Path ( "foo.c" ) ;
500
379
{
501
380
let r = io:: file_writer( & pth, [ io:: Create ] ) ;
502
381
r. unwrap( ) . write_str( "int main() { return 0; }" ) ;
503
382
}
504
383
505
- let db_path = os:: self_exe_path( ) . expect( "workcache::test failed" ) . pop( ) . push( "db.json" ) ;
506
- if os:: path_exists( & db_path) {
507
- os:: remove_file( & db_path) ;
508
- }
509
-
510
- let cx = Context :: new( RWArc :: new( Database :: new( db_path) ) ,
384
+ let cx = Context :: new( RWArc :: new( Database :: new( Path ( "db.json" ) ) ) ,
511
385
RWArc :: new( Logger :: new( ) ) ,
512
386
Arc :: new( TreeMap :: new( ) ) ) ;
513
387
0 commit comments