83 msg + " " + quote(name) + " for theory " + quote(theory_name) |
83 msg + " " + quote(name) + " for theory " + quote(theory_name) |
84 |
84 |
85 def compound_name(a: String, b: String): String = a + ":" + b |
85 def compound_name(a: String, b: String): String = a + ":" + b |
86 |
86 |
87 def empty_entry(theory_name: String, name: String): Entry = |
87 def empty_entry(theory_name: String, name: String): Entry = |
88 Entry("", theory_name, name, false, Future.value(false, Bytes.empty), XZ.Cache.none) |
88 Entry("", theory_name, name, false, Future.value(false, Bytes.empty), XML.Cache.none) |
89 |
89 |
90 sealed case class Entry( |
90 sealed case class Entry( |
91 session_name: String, |
91 session_name: String, |
92 theory_name: String, |
92 theory_name: String, |
93 name: String, |
93 name: String, |
94 executable: Boolean, |
94 executable: Boolean, |
95 body: Future[(Boolean, Bytes)], |
95 body: Future[(Boolean, Bytes)], |
96 cache: XZ.Cache) |
96 cache: XML.Cache) |
97 { |
97 { |
98 override def toString: String = name |
98 override def toString: String = name |
99 |
99 |
100 def compound_name: String = Export.compound_name(theory_name, name) |
100 def compound_name: String = Export.compound_name(theory_name, name) |
101 |
101 |
108 def text: String = uncompressed.text |
108 def text: String = uncompressed.text |
109 |
109 |
110 def uncompressed: Bytes = |
110 def uncompressed: Bytes = |
111 { |
111 { |
112 val (compressed, bytes) = body.join |
112 val (compressed, bytes) = body.join |
113 if (compressed) bytes.uncompress(cache = cache) else bytes |
113 if (compressed) bytes.uncompress(cache = cache.xz) else bytes |
114 } |
114 } |
115 |
115 |
116 def uncompressed_yxml: XML.Body = |
116 def uncompressed_yxml: XML.Body = |
117 YXML.parse_body(UTF8.decode_permissive(uncompressed)) |
117 YXML.parse_body(UTF8.decode_permissive(uncompressed)) |
118 |
118 |
156 (theory_name: String, name: String) => |
156 (theory_name: String, name: String) => |
157 regex.pattern.matcher(compound_name(theory_name, name)).matches |
157 regex.pattern.matcher(compound_name(theory_name, name)).matches |
158 } |
158 } |
159 |
159 |
160 def make_entry( |
160 def make_entry( |
161 session_name: String, args: Protocol.Export.Args, bytes: Bytes, |
161 session_name: String, args: Protocol.Export.Args, bytes: Bytes, cache: XML.Cache): Entry = |
162 cache: XZ.Cache): Entry = |
|
163 { |
162 { |
164 val body = |
163 val body = |
165 if (args.compress) Future.fork(bytes.maybe_compress(cache = cache)) |
164 if (args.compress) Future.fork(bytes.maybe_compress(cache = cache.xz)) |
166 else Future.value((false, bytes)) |
165 else Future.value((false, bytes)) |
167 Entry(session_name, args.theory_name, args.name, args.executable, body, cache) |
166 Entry(session_name, args.theory_name, args.name, args.executable, body, cache) |
168 } |
167 } |
169 |
168 |
170 def read_entry( |
169 def read_entry(db: SQL.Database, cache: XML.Cache, |
171 db: SQL.Database, cache: XZ.Cache, |
|
172 session_name: String, theory_name: String, name: String): Option[Entry] = |
170 session_name: String, theory_name: String, name: String): Option[Entry] = |
173 { |
171 { |
174 val select = |
172 val select = |
175 Data.table.select(List(Data.executable, Data.compressed, Data.body), |
173 Data.table.select(List(Data.executable, Data.compressed, Data.body), |
176 Data.where_equal(session_name, theory_name, name)) |
174 Data.where_equal(session_name, theory_name, name)) |
186 } |
184 } |
187 else None |
185 else None |
188 }) |
186 }) |
189 } |
187 } |
190 |
188 |
191 def read_entry( |
189 def read_entry(dir: Path, cache: XML.Cache, |
192 dir: Path, cache: XZ.Cache, |
|
193 session_name: String, theory_name: String, name: String): Option[Entry] = |
190 session_name: String, theory_name: String, name: String): Option[Entry] = |
194 { |
191 { |
195 val path = dir + Path.basic(theory_name) + Path.explode(name) |
192 val path = dir + Path.basic(theory_name) + Path.explode(name) |
196 if (path.is_file) { |
193 if (path.is_file) { |
197 val executable = File.is_executable(path) |
194 val executable = File.is_executable(path) |
203 } |
200 } |
204 |
201 |
205 |
202 |
206 /* database consumer thread */ |
203 /* database consumer thread */ |
207 |
204 |
208 def consumer(db: SQL.Database, cache: XZ.Cache): Consumer = new Consumer(db, cache) |
205 def consumer(db: SQL.Database, cache: XML.Cache): Consumer = new Consumer(db, cache) |
209 |
206 |
210 class Consumer private[Export](db: SQL.Database, cache: XZ.Cache) |
207 class Consumer private[Export](db: SQL.Database, cache: XML.Cache) |
211 { |
208 { |
212 private val errors = Synchronized[List[String]](Nil) |
209 private val errors = Synchronized[List[String]](Nil) |
213 |
210 |
214 private val consumer = |
211 private val consumer = |
215 Consumer_Thread.fork_bulk[(Entry, Boolean)](name = "export")( |
212 Consumer_Thread.fork_bulk[(Entry, Boolean)](name = "export")( |
269 def focus(other_theory: String): Provider = this |
266 def focus(other_theory: String): Provider = this |
270 |
267 |
271 override def toString: String = context.toString |
268 override def toString: String = context.toString |
272 } |
269 } |
273 |
270 |
274 def database( |
271 def database(db: SQL.Database, cache: XML.Cache, session_name: String, theory_name: String) |
275 db: SQL.Database, cache: XZ.Cache, |
272 : Provider = |
276 session_name: String, theory_name: String): Provider = |
273 { |
277 new Provider { |
274 new Provider { |
278 def apply(export_name: String): Option[Entry] = |
275 def apply(export_name: String): Option[Entry] = |
279 read_entry(db, cache, session_name, theory_name, export_name) |
276 read_entry(db, cache, session_name, theory_name, export_name) |
280 |
277 |
281 def focus(other_theory: String): Provider = |
278 def focus(other_theory: String): Provider = |
282 if (other_theory == theory_name) this |
279 if (other_theory == theory_name) this |
283 else Provider.database(db, cache, session_name, other_theory) |
280 else Provider.database(db, cache, session_name, other_theory) |
284 |
281 |
285 override def toString: String = db.toString |
282 override def toString: String = db.toString |
286 } |
283 } |
|
284 } |
287 |
285 |
288 def snapshot(snapshot: Document.Snapshot): Provider = |
286 def snapshot(snapshot: Document.Snapshot): Provider = |
289 new Provider { |
287 new Provider { |
290 def apply(export_name: String): Option[Entry] = |
288 def apply(export_name: String): Option[Entry] = |
291 snapshot.exports_map.get(export_name) |
289 snapshot.exports_map.get(export_name) |
300 } |
298 } |
301 |
299 |
302 override def toString: String = snapshot.toString |
300 override def toString: String = snapshot.toString |
303 } |
301 } |
304 |
302 |
305 def directory( |
303 def directory(dir: Path, cache: XML.Cache, session_name: String, theory_name: String) |
306 dir: Path, cache: XZ.Cache, |
304 : Provider = |
307 session_name: String, theory_name: String): Provider = |
305 { |
308 new Provider { |
306 new Provider { |
309 def apply(export_name: String): Option[Entry] = |
307 def apply(export_name: String): Option[Entry] = |
310 read_entry(dir, cache, session_name, theory_name, export_name) |
308 read_entry(dir, cache, session_name, theory_name, export_name) |
311 |
309 |
312 def focus(other_theory: String): Provider = |
310 def focus(other_theory: String): Provider = |
313 if (other_theory == theory_name) this |
311 if (other_theory == theory_name) this |
314 else Provider.directory(dir, cache, session_name, other_theory) |
312 else Provider.directory(dir, cache, session_name, other_theory) |
315 |
313 |
316 override def toString: String = dir.toString |
314 override def toString: String = dir.toString |
317 } |
315 } |
|
316 } |
318 } |
317 } |
319 |
318 |
320 trait Provider |
319 trait Provider |
321 { |
320 { |
322 def apply(export_name: String): Option[Entry] |
321 def apply(export_name: String): Option[Entry] |
362 (theory_name, name) <- export_names if matcher(theory_name, name) |
361 (theory_name, name) <- export_names if matcher(theory_name, name) |
363 } yield (theory_name, name)).toSet |
362 } yield (theory_name, name)).toSet |
364 for { |
363 for { |
365 (theory_name, group) <- exports.toList.groupBy(_._1).toList.sortBy(_._1) |
364 (theory_name, group) <- exports.toList.groupBy(_._1).toList.sortBy(_._1) |
366 name <- group.map(_._2).sorted |
365 name <- group.map(_._2).sorted |
367 entry <- read_entry(db, store.xz_cache, session_name, theory_name, name) |
366 entry <- read_entry(db, store.cache, session_name, theory_name, name) |
368 } { |
367 } { |
369 val elems = theory_name :: space_explode('/', name) |
368 val elems = theory_name :: space_explode('/', name) |
370 val path = |
369 val path = |
371 if (elems.length < export_prune + 1) { |
370 if (elems.length < export_prune + 1) { |
372 error("Cannot prune path by " + export_prune + " element(s): " + Path.make(elems)) |
371 error("Cannot prune path by " + export_prune + " element(s): " + Path.make(elems)) |