[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: "too many open files" error for an unknown reason

From: Jeff Kingston
Subject: Re: "too many open files" error for an unknown reason
Date: Sun, 22 Dec 2002 10:11:42 +1100

This was rather nasty.  The problem was that your @pageList
symbol had a parameter @pageFooter whose value Lout was
unable to determine in any simple way, since it required
knowledge of the number of the last page of the document.

This meant that for Lout to determine the value of
@pageFooter on page n, it could do no better than
find the value of @pageFooter on page n-1, for all
n.  Consequently to determine the value of @pageFooter n
it had to consult the database file about n times.  I'm
not quite sure whether it was really reopining the database
file again and again; I think at a lower level it was
just fseeking, but higher up it thought it was reopening.
There is a limit on the number of files you can have open
at any time, basically it's there to stop mutually recursive
file inclusions form playing total havoc.

Since @pageFooter was not really dependent on all those
earlier values I was able to rewrite your code to get
right of the parameter (see below), and then it all
worked for me.

There might be something buried in the Expert's Guide
about this, I'm not sure now.

I mean, to get *rid* of the parameter.

Jeff Kingston
def @document
  named @Tag {}
  right y
  def @text force into { @textPlace&&preceding } right y { y }

  def @numberOfPages { { @page&&@Tag } @Open { @pageNumber } }

  def @pageNumber
    @page&&preceding @Open { @pageNumber }

  def @pageFooter { @pageNumber"/"@numberOfPages }

  def @pageList
    right @pageNumber
    @page @pageFooter { @pageFooter } @pageNumber
    @pageList @Next @pageNumber

  { Courier Base 12p } @Font
  { ragged 1.20fx nohyphen } @Break
  { English } @Language
  { 0.0 0.0 0.0 setrgbcolor } @SetColor
    @pageList 1
  @text { y // @page&&preceding @Tagged @Tag }

ps It's hard to explain this, but if you are familiar with
functional languages, then Lout basically uses lazy evaluation,
except that when saving to a database it tries to do eager
optimizations.  If the parameters of a symbol that is being
saved to the database can be evaluated easily, then just
the symbol and its evaluated parameters need to be written.
If they can't be evaluated easily, then Lout is forced to
save the symbol, its unevaluated parameters, and their
enclosing environments.  In your case theis meant that
to save @pageList n Lout was being forced to save
a reference to @pageList n-1, and so on back to @pageList 1.

If you want to see this, have a look in foo.lout.ld after
the first run.  You'll see some entries of the form

    @@D "<fseekpos> <linenum>"

and you'll be able to see that these form a chain from
the last @pageList back to the first; whereas in my
revised version the only @@D stored in the file refers
back to @document, not the preceding @pageList.

pps Your approach will hog memory on large documents,
because @document is not a galley and hence Lout will
need to read it and its right parameter completely
before evaluating it.  It can only read one paragraph
at a time when it is reading through the right parameter
of a galley, not when reading the right parameter of
an arbitrary symbol.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]