Creating a Database
william chan
Posts: 1,326
Hi,
Let's say I need a create a database of 3 field records in a DAT section.
The fields are
1. Enumeration (long)
2. String (length of bytes 15-30)
3. Price in dollars (long)
How do I declare such a database in the DAT section?
Thanks.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.fd.com.my
www.mercedes.com.my
Let's say I need a create a database of 3 field records in a DAT section.
The fields are
1. Enumeration (long)
2. String (length of bytes 15-30)
3. Price in dollars (long)
How do I declare such a database in the DAT section?
Thanks.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.fd.com.my
www.mercedes.com.my
Comments
then make each entry 10 longs in length or use a searchable delimiter to show the seperation, or make a table of content. fixed length is best and easiest if you have a fairly fixed length to your field values.
William, what does "String (length of bytes 15-30)" mean?
Added: The pointers example just shows the math of access. Better design would be to have accessor methods to hide the details. Cheers.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Post Edited (jazzed) : 1/22/2009 1:09:46 AM GMT
After the code is run price contains the cost of the item i in pennies and strptr can be used·as if you were declaring string("...").
You could extend this to be an expandable database by padding recidx with additional values of zero for whatever the maximum number of records you'll allow are ( ....., @r4, 0[noparse][[/noparse]MAX_ADDREC]), and at the end of defined records you would declare enough longs to encompass all the anticipated·records followed by·RECEND BYTE 0.
When you add a record you iterate through recidx until you find a 0, then compare the location's address with r1 to make sure it is =< 8 bytes from r1 (room to add a record and still have a trailing 0L),·find the end of the last record by searching through the last record's string for a 0 byte. The next·long aligned address is the start of the new record, record this value in·open recidx slot you found and add the record info. But when you do this you must boundry check to make sure that the final location used is less than RECEND. If there isn't room for the index or the record you should not enter the record and exit gracefully.
You can speed up entering records by using another variable NumRec that is the index of·the last used record (the space for this variable is reclaimed by not having·a trailing 0 in recidx), then use the next recidx entry to indicate what address·a new record would go.
You didn't state if this was to be an exapandable or static database, if my instructions for an expandable database aren't clear enough for you to code yourself and thats what you need, I can whip it up for you.·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Post Edited (Paul Baker) : 1/21/2009 10:53:12 PM GMT
isnt doing what you think, it's assigning the address returned by string("... rather than copying the string itself, bytemove should be used to copy the contents. (you could use a pointer there, but your declaration of 32 bytes indicate this wasn't what you were attempting)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Your idea of inherent enumeration is ingenious!
Where did you learn to code like that?
I just don't quite understand this code
recptr := LONG[noparse][[/noparse]@recidx][noparse][[/noparse] i ]
where you can find a record's starting position so easily even with variable length strings.
What's the meaning of LONG when used as a functor? ( i hope you know what i mean )
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.fd.com.my
www.mercedes.com.my
Basically recidx is an array of addresses that point to the beginning of each record, and is therefore easy to populate by just filling it with the addresses of the record labels. So the variableness of the records is hidden in this array by simply having each entry point to the right place. Another not so obvious thing is to put the fixed part of the record first so that you always know thier offset in the record. The first variable length field is also easily accessed because we always know the offset where it starts since everything preceeding it is fixed length. The ugliness starts when you have more than one variable length field (which you fortunately don't have).
LONG[noparse][[/noparse]@recidx][noparse][[/noparse] i ] is treating hub memory as one huge array of longs, [noparse][[/noparse]@recidx] is the base, and [noparse][[/noparse] i ] is the offset, IOW starting at address recidx return the ith long (in other languages this would be recidx[noparse][[/noparse] i ] where recidx is declared as an array of longs). So this is a way of treating data in the DAT section as an array. Since what is stored in the array is an absolute address of the ith record, to get the price (the 1st long in the record) you use LONG[noparse][[/noparse]recptr] to fetch the value located there, if there was a second long value stored after the price it would be accessed with LONG[noparse][[/noparse]recptr][noparse][[/noparse] 1 ], or starting at address stored in recptr return the 2nd long (remember an array's first index is 0, so 1 is the 2nd long in the record).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Post Edited (Paul Baker) : 1/21/2009 11:22:26 AM GMT
Yep. I was tired.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
But it isn't the absolute address, it's an object-relative address. You need to use @@ to get the absolute address:
recptr := @@LONG[noparse][[/noparse]@recidx][noparse][[/noparse] i ]
I stand corrected, read posts below.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Post Edited (Paul Baker) : 1/21/2009 10:46:00 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Out of curiosity did your @@LONG[noparse][[/noparse].. work?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
This is the one time where @@ is needed, when you are recording·an address·in a DAT (compile time), since the objects haven't been linked yet there's no way to compute the final absolute address so the relative object address·is stored and the @@ operator indicates to the spin interpreter that it needs to add the object's base address to arrive at the absolute address.··Thanks for pointing out the error mpark.
Turns out the compiler allows you to use a DAT label as an array. (LONG[noparse][[/noparse]label][noparse][[/noparse] i ] also works but it's more verbose).·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Post Edited (Paul Baker) : 1/21/2009 11:02:29 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Ok, this uses an explicit record count to get around the issue created by using @@. The @@ also complicates dynamic records because at run time you're dealing with absolute addresses, so to enter a new value into recidx you will need to figure out how to subtract the abject base address so that the values can be reconstituted through @@ like the static records are.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Also, @@0 gives you the object base address if you want to convert from absolute addresses to object-relative.
Is it to save space?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.fd.com.my
www.mercedes.com.my
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker