src/Pure/Thy/export.scala
changeset 73031 f93f0597f4fb
parent 73024 337e1b135d2f
child 73033 d2690444c00a
equal deleted inserted replaced
73030:72a8fdfa185d 73031:f93f0597f4fb
    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))