Re: [sqlite] Interrupting SQLite execution (mainly FTS)

2013-05-02 Thread Dan Kennedy
On Thu, 2 May 2013 16:58:01 +0200
"Jan Slodicka"  wrote:

> Hi Dan
> 
> > What are your settings for pragmas "cache_size", "journal_mode" and
> > "synchronous"?
> 
> cache_size/synchronous - default values
> 
> Don't remember, which journal_mode was used for testing. Should be
> WAL, but I might have been lazy to write needed code. The source code
> was meanwhile modified, but I can write it again if necessary.

Maybe the delay at the end of the operation was an automatic 
checkpoint. I think that would explain why sqlite3_interrupt() 
and the others did not help.

Maybe you can run the checkpoint in a background thread after
rebuilding the FTS index or something.

If you don't mind locking the database, you could also try the
rebuild in rollback mode. It might be a little slower overall,
but it might also be more responsive as far as 
sqlite3_interrupt() goes.


___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Interrupting SQLite execution (mainly FTS)

2013-05-02 Thread Jan Slodicka
Hi Dan

> What are your settings for pragmas "cache_size", "journal_mode" and 
> "synchronous"?

cache_size/synchronous - default values

Don't remember, which journal_mode was used for testing. Should be WAL, but I 
might have been lazy to write needed code.
The source code was meanwhile modified, but I can write it again if necessary.

Jan
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Interrupting SQLite execution (mainly FTS)

2013-05-02 Thread Simon Slavin

On 2 May 2013, at 2:57pm, Jan Slodicka  wrote:

> LIKE is used at the moment, but it has its perf limits as well. To prove it,
> here is a desktop benchmark:
> 
> Desktop: W7, x64, Intel i5, 2.4 GHz
> 116 MB email table containing 1 html-formatted emails.
> SELECT ... LIKE...'%xxx%'... command took 35.5 sec. (Producing 9 results)
> SELECT ... MATCH ... 'xxx*' command took 0.00 sec, i.e. somewhere between
> 0-7 msec. (By chance producing the same results)
> 
> The funny thing was that the creation of the email FTS index took 22-23 sec,
> i.e. was faster than a single LIKE statement.

Thank you for this interesting and surprising information.  The resource and 
time cost of doing any writing on a mobile device is usually far greater than 
simply doing processing in memory.  It appears that this is not true in your 
case.  Hmm.

> My plan is to implement FTS search as an optional feature:
> - Several FTS indexes grouped into multi-indexes (Example: people names may
> be in one of 3 tables: accounts, contacts, leads. These tables would
> contribute to PeopleSearch activity.)
> - FTS index is built on demand (when the user tries to use it)
> - The build procedure must be cancellable
> - Once built, the index will be maintained using triggers (for small data
> changes)
> - For large data changes (happens during synchronization when the server
> sends a lot of data) the FTS index is dropped
> 
> Do you see any risks with this scheme?

It appears that you are aware of the issues and have thought this through.  
Sorry for troubling you.

Simon.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Interrupting SQLite execution (mainly FTS)

2013-05-02 Thread Dan Kennedy
On Thu, 2 May 2013 11:16:06 +0200
"Jan Slodicka"  wrote:

> I was testing various ways how to interrupt rebuilding of an FTS
> index. Ability to abort is vital as the app is running on a
> smartphone and has to meet responsivity requirements.
> 
> Here is what SQLite offers (AFAIK):
> - Progress handler (with low nOps value): Relatively good with only
> occasional longer periods without progress handler invocation. High
> nOps values perform badly.
> - Authorizer: Does not help much in itself, but improves a bit the
> progress handler as it is called at different occasions.
> - sqlite3_interrupt(): Tested once per sqlite3VdbeExec() call (also
> during SQL parsing, sqlite3Step()...) => insufficient.
> 
> Suggestion:
> The progress handler is called when {operation_counter=i*nOps; i>0},
> whereby the counter is reset at entry to sqlite3VdbeExec() and then
> incremented for each VDBE operation. This reset causes irregular
> behavior with occasional long periods without progress handler
> invocation. So the suggestion is: Make the counter global per DB
> connection and do not reset it.
> 
> The real problem is that even if I use all above tools (progress
> handler with nOps=1), there are relatively long periods when the
> execution cannot be interrupted. For example for a 30MB table (the
> user data may be larger) there is roughly 0.5 sec pause at the end
> (measured on the desktop!), maybe caused by journal maintenance.

What are your settings for pragmas "cache_size", "journal_mode" and
"synchronous"?

Dan.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Interrupting SQLite execution (mainly FTS)

2013-05-02 Thread Jan Slodicka
Hi Simon.

> I have much love for FTS but it chews up storage space, processing power,
and therefore battery life, something fierce.  You may end up with a working
app but your users will find it reduces their battery life to an hour.

Sounds unbelievable. Can you bring some example, please?

In the past we worked for example on smartphone backup solutions, i.e. long
running apps taking full processor power and writing a lot to SD cards
(which in my opinion drains battery more), but did not observe such dramatic
effect. (Or even worse battery "drainer": playing mp3 streamed over BT.)

> Do you really need to /build/ an FTS database on a phone app ?  Can you
not (A) do what you want to do with GLOB and LIKE or (B) build the database
externally before it's moved to the phone ?

The app serves as a CRM client with full editing abilities, synchronization
etc. Hence the data is live and cannot be pre-built.

LIKE is used at the moment, but it has its perf limits as well. To prove it,
here is a desktop benchmark:

Desktop: W7, x64, Intel i5, 2.4 GHz
116 MB email table containing 1 html-formatted emails.
SELECT ... LIKE...'%xxx%'... command took 35.5 sec. (Producing 9 results)
SELECT ... MATCH ... 'xxx*' command took 0.00 sec, i.e. somewhere between
0-7 msec. (By chance producing the same results)

The funny thing was that the creation of the email FTS index took 22-23 sec,
i.e. was faster than a single LIKE statement.



My plan is to implement FTS search as an optional feature:
- Several FTS indexes grouped into multi-indexes (Example: people names may
be in one of 3 tables: accounts, contacts, leads. These tables would
contribute to PeopleSearch activity.)
- FTS index is built on demand (when the user tries to use it)
- The build procedure must be cancellable
- Once built, the index will be maintained using triggers (for small data
changes)
- For large data changes (happens during synchronization when the server
sends a lot of data) the FTS index is dropped

Do you see any risks with this scheme?

Jan


___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Interrupting SQLite execution (mainly FTS)

2013-05-02 Thread Simon Slavin

On 2 May 2013, at 10:16am, "Jan Slodicka"  wrote:

> I was testing various ways how to interrupt rebuilding of an FTS index.
> Ability to abort is vital as the app is running on a smartphone and has to
> meet responsivity requirements.

Sorry, I don't know an answer to your question, but I do have an observation.

I have much love for FTS but it chews up storage space, processing power, and 
therefore battery life, something fierce.  You may end up with a working app 
but your users will find it reduces their battery life to an hour.

Do you really need to /build/ an FTS database on a phone app ?  Can you not (A) 
do what you want to do with GLOB and LIKE or (B) build the database externally 
before it's moved to the phone ?

Simon.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Interrupting SQLite execution (mainly FTS)

2013-05-02 Thread Jan Slodicka
I was testing various ways how to interrupt rebuilding of an FTS index.
Ability to abort is vital as the app is running on a smartphone and has to
meet responsivity requirements.

Here is what SQLite offers (AFAIK):
- Progress handler (with low nOps value): Relatively good with only
occasional longer periods without progress handler invocation. High nOps
values perform badly.
- Authorizer: Does not help much in itself, but improves a bit the progress
handler as it is called at different occasions.
- sqlite3_interrupt(): Tested once per sqlite3VdbeExec() call (also during
SQL parsing, sqlite3Step()...) => insufficient.

Suggestion:
The progress handler is called when {operation_counter=i*nOps; i>0}, whereby
the counter is reset at entry to sqlite3VdbeExec() and then incremented for
each VDBE operation. This reset causes irregular behavior with occasional
long periods without progress handler invocation.
So the suggestion is: Make the counter global per DB connection and do not
reset it.

The real problem is that even if I use all above tools (progress handler
with nOps=1), there are relatively long periods when the execution cannot be
interrupted. For example for a 30MB table (the user data may be larger)
there is roughly 0.5 sec pause at the end (measured on the desktop!), maybe
caused by journal maintenance.

In my opinion I would not have this problem if the (external content) FTS
index could be placed into an attached database. Then
a) The FTS DB could be set up for highest performance / lowest safety. (No
journal, for example)
b) The long actions could be performed in a thread that could be killed if
necessary.

However,  FTS design doesn't seem to enable that. (Would deserve separate
discussion. Main problem for me is that the triggers cannot refer to an
attached DB.)

Any advice?

Thanks in advance,
Jan Slodicka


___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Interrupting sqlite

2009-06-23 Thread Rich Rattanni
Would forking another process as a worker process be acceptable, then
in your main message loop wait for some IPC signal saying it is done?
Unless you are doing this on some extremely lightweight OS / monitor
that doesn't implement the concept of time-sharing, I can't see how
this would be hard to do.

On Mon, Jun 22, 2009 at 8:23 PM, João Eiras wrote:
> On , Dan  wrote:
>
>>> My doubt is the following: if from the progress callback (set with
>>> sqlite3_progress_handler) I return non 0 and therefore I get
>>> SQLITE_INTERRUPT from the call to sqlite3_step, is the sqlite3_stmt
>>> object still in a valid state and will the query resume normally if I
>>> pass the same sqlite3_stmt object back to sqlite3_step again ?
>>
>> No. Next call on the statement handle should be sqlite3_reset() or
>> sqlite3_finalize().
>>
>
> I have tested it and I clearly confirm your comment :)
>
> On , Roger Binns  wrote:
>
>> Why don't you call the main message loop from within the progress
>> handler callback?
>>
>
> Unfortunately, it's not that simple. The message loop loops both UI messages 
> and customs messages internal to the application. For instance, I keep track 
> of a sql statement in a object. The statement evolves after that object being 
> affected a few times by execution messages. This way everything has their 
> share of CPU and the ui works, while not relying on threading, because 
> threading would require architectural and design changes in the application.
> However, this is also one of the downfalls. I can have an arbitrary amount of 
> sqlite databases open, and if I run the message loop inside the progress 
> handler, I can theoretically have infinite reentrancy, where one progress 
> handler executes something on a different database, being in practice limited 
> by stack size, which would cause a crash.
> Also, requesting the message loop to run has its performance penalty, so it 
> lags the query a bit more than what's ideal.
>
> Thank you for those suggestions, but I have though of many other options, 
> those included.
>
>
> So, today I was looking around the sqlite code and try to make this a 
> reality, which is after interrupting a statement with a progress callback, 
> leaving the sqlite3_stmt object in a state that can be resumed with another 
> sqlite3_step call.
> It turned out a few lines of code fix, but however it had a side effect. 
> Internally, sqlite uses sqlite3_exec function and editing the code around 
> those calls to store state to allow sqlite3_exec to be suspendable as well is 
> not trivial nor simple. But I'm not using sqlite3_exec on my application, so 
> I just editied this function on my local tree to set the progress handler to 
> null and restore it in the end.
>
> I code I needed to change to allow sqlite3_step to resume was just the 
> following in file vdbe.c around line 5285, in function sqlite3VdbeExec:
>
>   vdbe_error_halt:
>     assert( rc );
>     p->rc = rc;
> +   if (rc != SQLITE_INTERRUPT){
>       sqlite3VdbeHalt(p);
> -
> +   }
> +   else
> +   {
> +       p->nCallback++;
> +       p->pc = pc;
> +   }
>     if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
>     rc = SQLITE_ERROR;
>
>
> This is probably not enough, and could even had some side effects, none of 
> which I encountered, because I have my own test suite for my own cases.
>
> The question then becomes, would sqlite be able to support such thing in the 
> future (suspending/resuming) ?
>
> Thank you for your attention.
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Interrupting sqlite

2009-06-22 Thread João Eiras
On , Dan  wrote:

>> My doubt is the following: if from the progress callback (set with
>> sqlite3_progress_handler) I return non 0 and therefore I get
>> SQLITE_INTERRUPT from the call to sqlite3_step, is the sqlite3_stmt
>> object still in a valid state and will the query resume normally if I
>> pass the same sqlite3_stmt object back to sqlite3_step again ?
>
> No. Next call on the statement handle should be sqlite3_reset() or
> sqlite3_finalize().
>

I have tested it and I clearly confirm your comment :)

On , Roger Binns  wrote:

> Why don't you call the main message loop from within the progress
> handler callback?
>

Unfortunately, it's not that simple. The message loop loops both UI messages 
and customs messages internal to the application. For instance, I keep track of 
a sql statement in a object. The statement evolves after that object being 
affected a few times by execution messages. This way everything has their share 
of CPU and the ui works, while not relying on threading, because threading 
would require architectural and design changes in the application.
However, this is also one of the downfalls. I can have an arbitrary amount of 
sqlite databases open, and if I run the message loop inside the progress 
handler, I can theoretically have infinite reentrancy, where one progress 
handler executes something on a different database, being in practice limited 
by stack size, which would cause a crash.
Also, requesting the message loop to run has its performance penalty, so it 
lags the query a bit more than what's ideal.

Thank you for those suggestions, but I have though of many other options, those 
included.


So, today I was looking around the sqlite code and try to make this a reality, 
which is after interrupting a statement with a progress callback, leaving the 
sqlite3_stmt object in a state that can be resumed with another sqlite3_step 
call.
It turned out a few lines of code fix, but however it had a side effect. 
Internally, sqlite uses sqlite3_exec function and editing the code around those 
calls to store state to allow sqlite3_exec to be suspendable as well is not 
trivial nor simple. But I'm not using sqlite3_exec on my application, so I just 
editied this function on my local tree to set the progress handler to null and 
restore it in the end.

I code I needed to change to allow sqlite3_step to resume was just the 
following in file vdbe.c around line 5285, in function sqlite3VdbeExec:

   vdbe_error_halt:
 assert( rc );
 p->rc = rc;
+   if (rc != SQLITE_INTERRUPT){
   sqlite3VdbeHalt(p);
-
+   }
+   else
+   {
+   p->nCallback++;
+   p->pc = pc;
+   }
 if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
 rc = SQLITE_ERROR;


This is probably not enough, and could even had some side effects, none of 
which I encountered, because I have my own test suite for my own cases.

The question then becomes, would sqlite be able to support such thing in the 
future (suspending/resuming) ?

Thank you for your attention.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Interrupting sqlite

2009-06-22 Thread Roger Binns
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

João Eiras wrote:
> My doubt is the following: if from the progress callback (set with
> sqlite3_progress_handler)

Why don't you call the main message loop from within the progress
handler callback?

Roger
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAko/1ygACgkQmOOfHg372QTYhQCfVclgRW0huXzkHanMyoNa0lts
ShQAoOKPhA+En5cve77wrZAVjl/fVOhG
=42Tg
-END PGP SIGNATURE-
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Interrupting sqlite

2009-06-22 Thread Dan

On Jun 22, 2009, at 6:10 PM, João Eiras wrote:

> Hello!
>
> I developing an single threaded app (pre-established fact, can't
> change this), and to keep the UI usable, when sqlite is executing,
> between multiple calls to sqlite3_step, I just break away and let the
> main message loop run a bit more. If the query i executing has an
> "order by" clause, then sqlite3_step will not return until it has
> processed the entire result set in memory, so it can be sorted.
>
> My doubt is the following: if from the progress callback (set with
> sqlite3_progress_handler) I return non 0 and therefore I get
> SQLITE_INTERRUPT from the call to sqlite3_step, is the sqlite3_stmt
> object still in a valid state and will the query resume normally if I
> pass the same sqlite3_stmt object back to sqlite3_step again ?

No. Next call on the statement handle should be sqlite3_reset() or
sqlite3_finalize().

Dan.


> This
> way I could try to interrupt the statement many times so I can
> continue to process the main loop to get the UI going.
>
> Thanks.
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Interrupting sqlite

2009-06-22 Thread João Eiras
Hello!

I developing an single threaded app (pre-established fact, can't
change this), and to keep the UI usable, when sqlite is executing,
between multiple calls to sqlite3_step, I just break away and let the
main message loop run a bit more. If the query i executing has an
"order by" clause, then sqlite3_step will not return until it has
processed the entire result set in memory, so it can be sorted.

My doubt is the following: if from the progress callback (set with
sqlite3_progress_handler) I return non 0 and therefore I get
SQLITE_INTERRUPT from the call to sqlite3_step, is the sqlite3_stmt
object still in a valid state and will the query resume normally if I
pass the same sqlite3_stmt object back to sqlite3_step again ? This
way I could try to interrupt the statement many times so I can
continue to process the main loop to get the UI going.

Thanks.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users