Re: Caching in the dynamic database

"Richard A. O'Keefe" <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
On 13/02/2014, at 6:22 PM, Michael Ben Yosef wrote:

> Hi Richard,
> 
>> Before trying anything exotic, is there any possible
>> refactoring of the existing data to take less memory to
>> start with?
> 
> I must confess I don't have any existing data in mind. I was
> considering it as a purely intellectual exercise. That is, suppose we
> are working with some data that is definitely larger than memory.
> Let's say that it's in the form of an external relational database.

Hold it right there.

The following observation has nothing to do with Prolog,
and everything to do with relational databases and what
the *point* of a relational database is.

If you are interfacing to a database from *any* language
and you do your own caching and the database engine does
not know about the caching you are doing and has no way
to invalidate your cache, then you *WILL* lose the ACID
guarantees and eventually you *WILL* get inconsistent
results.

You can get away with your own caching if (and I would like
to say only if):
 - nobody at all is changing the data, or
 - you are changing the data and nobody else is looking at it, or
 - you keep the database engine fully informed of what you are
   up to and give it the power to invalidate your cache.

> Every time we read from or write to the database we do I/O, possibly
> over a network.

That need not be true.  SQLite famously works in-memory.
FireBird (www.firebird.org) is a long-established full-featured
SQL database comes in that four versions, one of them "embedded",
http://www.firebirdsql.org/manual/fbmetasecur-embedded.html

What happens with that is that you link the database engine
as part of your program and you talk to it directly.  The
cost of a call to the database is pretty light, and the
huge thing here is that

	THE DATA BASE DOES THE CACHING

so you are not losing any of the benefits of using a
relational data base.

> For many common access patterns it would be much
> faster to cache as much as possible of this external database as facts
> in Prolog's dynamic database.

It is or can be orders of magnitude faster to use Prolog
*instead of* a relational database.  But looking at a system
as a whole, the setup you describe has caching done *twice*.
(Prolog caching stuff and the database caching the same stuff.)
That's going to make *less* memory available overall.
But the worst of it is that there's no cache coherence protocol
to keep the two caches consistent.  Using Firebird embedded
you do still have to pay the price of converting data between
Prolog format and database format, BUT you get *SAFE* caching.

> What I was asking was, "How much is as much as possible?".

The answer depends on what _else_ is happening on the same
machine.  

> For example, if every time I read a row from from
> the database I assert a fact for it, how do I know when I'm starting
> to fill up memory and I should retract a few lesser used facts before
> asserting any new ones?

Let's return to my question.
>> 
>> Before trying anything exotic, is there any possible
>> refactoring of the existing data to take less memory to
>> start with?

The very fact that you speak of "read(ing) a row" suggests to
me that you might not be used to thinking in terms of column-
oriented databases like InfoBright or Monet or C-Store.  These
are SQL databases just like traditional row-oriented databases,
but they fetch from disc just the columns that are relevant to
your query.  (Apparently DB2 and SQL Server can be configured
to do this too, but I don't know the details.)  Bringing less
data from disc into the DB engine and importing less data from
the DB engine into Prolog is the first thing to try before any
fancy dialect-specific hacking on the guts of the Prolog clause
store.

I'd like to point out also that the Prolog clause store has always
been designed for *procedures*; clauses that might do serious
pattern matching and are likely to have significant bodies.
It is likely that a specialised storage system for predicates
containing only ground unit clauses could
 - take less space
 - make richer/better indexing straightforward
 - be cheaper to modify
I think if you want to cache (views of) relational data inside
Prolog, _this_ is the place to start, not the existing clause
store.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.