Thanks, Brian... yes, it does help. I'm far more concerned with memory usage
than speed, especially if a number of people are running the script at once.
Your tip looks very worthwhile!

--Ralph

> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]
> Sent: Friday, April 21, 2000 6:03 PM
> To: [EMAIL PROTECTED]
> Subject: [REBOL] online database manipulation Re:(3)
>
>
> Hi Ralph!
>
> Gabrielle wrote:
> > > Hello [EMAIL PROTECTED]!
> > >
> > > On 21-Apr-00, you wrote:
> > >
> > >  r>     a: read/lines %auto.db
> > >
> > >
> > >  r>     a: to-hash a
> > >
> > > You don't need a hash if you're just using functions like PICK and
> > > not FIND, SELECT etc. This conversion could take some time if the
> > > db is very big...
> > >
>
> You replied:
> > Thanks, Gabriele, but I am searching each line for a specific
> > string. I hope I am correct in that converting it to hash
> > speeds up such searches.
>
> Hashes only speed up searching if you arrange the data as in pairs,
> [key value key value ...]. It won't help your database directly,
> but would help if you used a hash as an index.
>
> Say %auto.db is a flat file with tab-delimited fields and line-
> delimited records. If you wanted a straight name index, and the
> name was in the first field, you could do something like this:
>
>     ; Split the database into records
>     a: read/lines %auto.db
>     ; Make index as block at first for insert speed
>     i: make block! 2 * length? a
>     foreach r a [
>         ; Split record into fields
>         r: parse/all r "^-"
>         ; Insert first field and record into index
>         i: insert insert i r/1 r
>     ]
>     ; Change index into hash for efficiency
>     i: make hash! head i
>     ; Now select the record as often as you want
>     result: select i value
>
> but that only makes sense if you are doing many searches in one
> transaction, quite unlike what you are doing on your web site.
>
> Instead, try this:
>
>     value: whatever...
>     lines: make list! 0  ; List for insertion speed/space
>     use [a rb re] [
>         ; Read the database in text mode
>         a: read %auto.db
>         ; Find the value in the database
>         while [re: find a value] [ ; Use find/any here?
>             ; Get the beginning of the record
>             either rb: find/reverse re newline [rb: next rb] [rb: a]
>             ; Get the end of the record
>             if none? re: find rb newline [re: tail rb]
>             ; Set the data to the next record
>             a: next re
>             ; Store a copy of the record, split into fields
>             lines: tail insert lines (parse (copy/part rb re) "^-")
>         ]
>     ]
>     ; Here are the found record lines
>     lines: head lines
>
> It may not be as pretty, but it's much faster and uses less
> memory as well. You can even add wildcard searching by using
> find/any instead of find where marked above, but that might
> find patterns that span records.
>
> I suppose that parse could be used instead, but I don't feel
> like figuring out how right now, and it would be about as fast.
>
> This technique does require you to read the entire database
> into memory for every transaction though, just like your first
> solution did. If you wanted to use open/lines instead of read
> you would be back to doing a find on each line in turn.
>
> Does this help?
>
> Brian Hawley
>


Reply via email to