"Sachin Gupta" <scgu...@ipolicynetworks.com>
schrieb im Newsbeitrag
news:51b335651c9a0c4ea520d47f23a580b414f5cd5...@sinnodmbx001.techmahindra.com...

> --- The Application will be using the in memory SQLite
> as Cache.
You could also consider some sort of "sorted Dictionary"
(a Tree-Structure which allows fast "sorted indexed-access")
instead of the SQLite-engine in this case.

> --- One thread in the application, is listening on the device
> and the data sent by the device is saved in the Cache or
> inserted to SQLite. This is the writer Thread.
Ah Ok, as guessed...

> --- Multiple GUI's are connected to the Application which are being
> serviced by individual threads. These Threads are interacting with the
> cache (SQLite) and providing data to the GUI(s). These are the
> Reader Threads.
Ok.

> --- The rate of data received at the Writer Thread will be varying.
> It is not constant as stated by me earlier.
No problem, if your previous reply was describing
a worst-case data-rate, then you're fine - you will only
need to "sleep" within your SQLite-Thread, if "no-next-job"
was found in your round-robin-cycling.

> --- At any instant of time, if the data rate from device is very high
> and simultaneously the GUI is asking for Data,  it is quite possible
> that Writer and Reader may collide.
That's clear, but there's no real collision possible (you don't
even need locking).
Your writer-devicethread will share a memory-structure with
the SQLite-thread, which in its first members is holding a
NextJobIndex (the index pointing into a JobQueue-array,
which at each index-position describes an entire new DataRow
(all the Fields which make up a new record) + a JobState-
EnumEntry (JobPreparing / JobPrepared / JobDone / JobFailed).

Same thing with your GUI-reader-threads (a Struct with
a NextJobIndex-member + a preallocated array which in
this case contains the same JobState-EnumEntry at
each array-index + a String-Entry for the Select-Command,
and a Resultset-pointer which will point to a copy of the
data, filled-in wihtin the sqlite_step-loop, when the SQLite-
thread is processing this current read-request.

Just ensure, that these shared structs hold JobQueue-arrays,
which are large enough to hold data for - let's say - 2-3
seconds worst-case incoming rate.

> Your Questions:
> Q1. Don't know, what you need these Reader-Threads for?
> Ans1: The application is client Server based, where there can
> be multiple instances of GUI connecting to the Application
> (running sqlite).
Till here, it is not yet entirely clear, what you mean (Client/Server
can mean anything) - please let's talk in terms of "processes"
and "threads".

When you talk about "multiple instances of GUI" - are these
instances running within the same process, which hosts your
SQLite-DBCache- and the DeviceWriter-Threads?

> The Application would handle display requests coming from
> these GUI threads. These are the reader threads.
This again sounds as if your "GUI-threads" and the "reader-
threads" are identically (and run within the same process).

> Q2. So, what is your usecase ... do you want to work with
> something like a ringbuffer? Are Deletes involved - and after
> what time do they begin "to kick in"?
> Ans2: Yes, kind of. We are using timers to maintain the size
> of the sqlite cache and limit it to a certain size (~1 Million Records)
> so that the DB does not bloat out of hand. We are using timers
> to click in every 15 seconds to delete the old records.
You will not need any timers for that, the isolated (single)
SQLite-Thread can take care of that whilst processing the
current insert (keeping a count-of already inserted records
in memory, you will not even need a "Select" for determining
the current recordcount).

> Questions:
> Ques. No there will be no such instances, since the InMemory-
> DB-Connection is used on only one thread - but that isn't
> really a problem, if you "do it right"...
> >>>> Does that mean that only one connection can be made
> to In Memory DB?
Yes, of course - but there's no real problem here with that,
because even one thread is enough in your case IMO
(because SQLite is fast enough in InMemory-Mode,
to give you the "illusion" of parallel processing of Write-
*and* Read-Requests, if you work in small enough
chunks (Write-direction inserting only 1-20 records at
a time - Read-Direction processing only one single
queued Select at a given time, which should be finished
within - let's say - 10msec.

> Ques: Does SQLite support Connection Pooling:
> Both for In Memory DB or Disk Based?
No - not in InMemory-Mode - and as said, not really
needed in your case.

> If not supported, then how can we handle multiple simultaneous
> accesses to DB (R-R,R-W,W-W)? Will we have to do
> concurrency handling by ourselves?
Of course - and it is not difficult, if you work with the
(isolated) mem-structures I've described already above.

Within the SQLite-Thread there's a loop:


While Not SQLiteThreadCancelled

  ActivitySteps = 0

  If WriterQ.JobArray(WriterQ.NextJobIndex).JobState = JobPrepared
      Result = DoInsert(WriterQ.JobArray(WriterQ.NextJobIndex).RecordData)
      WriterQ.JobArray(WriterQ.NextJobIndex).JobState = Result
      WriterQ.NextJobIndex = WriterQ.NextJobIndex + 1 Modulo WriterQ.Lenght
      If CurrentRecordCount > MaxDBRecords
          DeleteOldestRecord()
      End If
      ActivitySteps++
  End If

  ReaderQ = GetNextReadersQueueStruct_RoundRobin()
  If ReaderQ.JobArray(ReaderQ.NextJobIndex).JobState = JobPrepared
      Result = DoSelect(pResultSet ,
ReaderQ.JobArray(ReaderQ.NextJobIndex).SelectString)
      ReaderQ.JobArray(ReaderQ.NextJobIndex).JobState = Result
      ReaderQ.JobArray(ReaderQ.NextJobIndex).pResultSet = pResultSet
      ReaderQ.NextJobIndex = ReaderQ.NextJobIndex + 1 Modulo ReaderQ.Lenght
      ActivitySteps++
  End If

  If ActivitySteps = 0 Then
    Sleep 2
 End If

Loop


> If not supported, then is there any thirdparty providing support
> for Connection Pooling?
You don't really need such a thing, the above scheme is
"simple enough" and also responsive enough I'd say.


> Ques: Can we use "SQLite Shared-Cache Mode" with "In Memory"
> Databases?
No, as Igor already pointed out, Shared-Cache mode is there
for multiple Connections (running in their own threads and
working against a *file*-DB).
There's only *one* Connection possible to an InMemory-DB.

> Ques: You mentioned the following:
>   1. inserts of these 15 records in about 1-2msec max
>   2. it would be your responsibility, to perform only that many
>      of these queued selects, that you stay within your 8-10msec-
>      limit Idle-Time
>
> Are we gonna have to handle the read/write requests in our
> application so that we are able to create Idle Time between
> multiple writes?
Yes, using the above scheme. And there's automatically
"Idle Time between Requests", since SQLite is more than
fast enough in InMemory-Mode, to handle your incoming
write and read-requests, using the above mentioned loop.
If the max data-rates you mentioned earlier are correct -
and if your reader-queries perform usually faster than
10msec, then the SQLite-Thread will sit mostly there,
just sleeping.


> Ques: Am I correct in saying that you are only considering
> one thread that is handling both Read and Write requests
> in sequential manner?
Of course.
The usual TFT-Screenrefresh-Rates are 60-75Hz nowadays.
So you have about 12-15msec Intervals available between "new
GUI-RenderOutputs" anyways - and even if your Read-Queries
should take 20-25msec, you will only have to leave out one
Screen-Refresh, which would barely be noticed by a
User, looking at some "scrolling graph" or whatever.
As long as you achieve around 30Hz Screenrefresh, then
everything will look "movielike and smooth".

Olaf




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

Reply via email to