Last Updated: 9/25/2001
apack()/aunpack() in aruna.c
Purpose
License
Description
Dependencies
Limitations
Performance Considerations
To Do
Usage
Class Methods
Instance Methods
Testing
A_Debug Usage
Purpose:
This module provides to methods (apack and aunpack) that are very similar to Array.pack and String.unpack. These work exactly like pack and unpack but are tailored to support standard database objects such as short, integer, byte, char(), varchar, date, time, etc. These methods are used by A_Buffer to pack key/value pairs into the buffer for reading and writing. Since A_Table, A_Index use A_BTree for storing and retrieving data and A_BTree uses A_Buffer to store and retrieve data, each of the classes indirectly use apack and aunpack. A_Table uses the apack string for many standard column constraints.
Description:
Pack and unpack data into an A_Buffer object. See A_Buffer documention for details on how this uses apack/aunpack. See A_BTree documentation to see how to apack/aunpack is used indirectly to reduce disk space and increase performance. See A_Table and A_Index documentation to see how apack/aunpack is used indirectly for standard column constraint checking, to reduce disk space, and increase performance.
Valid or supported pack/unpack string elements:
- * - Marshal.dump/Marshal.load the value. This should used by itself with no other types regardless of how many elements are in the key. It is an all or nothing kind of thing. This will Marshal.dump/load the whole key/value.
- B - single unsigned byte
- b - single byte
- C - single unsigned char
- c - single char
- C# - space padded fixed length unsigned char string
- c# - space padded fixed length char string
- S - unsigned short (2 byte int) - little-endian
- s - short (2 byte int) - little-endian
- I - unsigned int (4 byte int) - little-endian
- i - int (4 byte int) - little-endian
- L - big unsigned int (8 byte int) - little-endian
- l - big int (8 byte int) - little-endian
- d - 8 byte double - little-endian
- v - null terminated varchar string
- V - null terminated varchar string
- v# - null terminated varchar string, size (#) is ignored
- V# - null terminated varchar string, size (#) is ignored
- D - date - currently this is a 4 byte value store is seconds since epoch (Ruby Date)
- T - time - currently this is a 4 byte value store is seconds since epoch (Ruby Date)
- t - date/time - currently this is a 4 byte value store is seconds since epoch (Ruby Date)
- p - A_Pos - 5 byte value stored as 1 byte file_no, 4 byte file pos, this is returned and used by A_FileStore.
-- not yet supported --
- b#:# - bits
- n#.# - numeric
- d#.# - decimal
- m - money
- f - Not supported because the precision is too difficult to manage - 4 byte float - little-endian
Dependencies:
None
Limitations:
There is some machine dependant code in this module that has not been tested on hardware other than Intel. If you are running on a Mac, OSF, HP, or other hardware than Intel, then please run and review the tests (tst_apack.rb) careful and make sure these methods work okay. Please email: new_hardware@arunadb.org if you successfully test a new platform so this page can be updated. Please email support@arunadb.org if are trying to port to an untested machine and you are having problems. This has been tested on the following platforms:
- Win95/WinNT 4.0/Win2000 on Intel
- FreeBSD 4.2 and linux (Red Hat 6.2) on Intel.
Not all Ruby data types are supported
This module may not work on all Ruby platforms. There is a lot of machine dependant code in this module that may not work for 64 bit, 16 bit computers. This was tested on Intel hardware and may need to be tweaked to run on Motorola hardware.
Performance Considerations:
Creating the buffer before calling the low level C functions rb_ary_apack_() and rb_ary_aunpack_() is faster than calling Array.apack and String.unpack. Of course, this means you have to write a
Use pack strings when you can. In most cases they are more efficient than Marshal.dump and Marshal.load.
To Do:
Add support for a bit data type allowing you to pack up to 8 boolean or bit values into a single byte.
Add support for numeric, decimal, and currency data types.
Add support for date/time < 1980 and > 2040 (these are limitations in Ruby's Date).
Make sure this runs adequately on all support Ruby platforms. I will need help with this one.
Usage:
N/A
Class Methods:
None
Instance Methods:
Array.asearch(value)
This performs a modified binary search on Array for value. This is a binary search on the elements in the array where the index of the first element >= value is returned. This is used by A_FileSort to determine which slot to put rows in as they are being sorted. A similar method can be found in A_Buffer.asearch.
value - is the value you are looking for in the array.
Array.apack(pack_string)
Pack the elements in the array according to the pack_string. Valid pack_string elements are described above. You can look at the documention for Array.pack for more details about how this works. Returns a String. There is a lower level C function that will pack the array directly into your buffer called rb_ary_apack_(). This low level C function is called by A_Buffer.c as key/value pairs are packed into the buffer.
String.aunpack(pack_string)
Unpack the elements in the String according to the pack_string. Valid pack_string elements are described above. You can look at the documention for String.unpack for more details about how this works. Returns an Array. There is a lower level C function that will pack the array directly into your buffer called rb_ary_aunpack_(). This low level C function is called by A_Buffer.c as key/value pairs are unpacked out of the buffer.
String.apack_size()
When string is valid pack string as defined above, this returns the size (in bytes) that will be used by this pack string.
Testing:
tst_apack.rb will test the basic functionality of apack() and aunpack(). To run type
Ruby -I.. tst_apack.rb
A_Debug Usage:
N/A