1. OK, so what about Encryption? I thought SHA-1 and 128 bit encryption was broken!
The Blogs define any successful attempt to find a hash key colision (duplicate key giving the same result) that is successful as a defect in the Encryption method.
2. Is it faster in VSAMEX to reference fields by number as apposed to name, and are the field numbers converted in the order that they appear in the VB/ISAM type format? Example: Is the first field of the record named Field1, the second - Field2 etc.?
The conversion process from VB/ISAM to VsamEx[treme] datasets is rather rapid and will be done the first time you use Vsam to access the older datasets. We fetch the old Format string and construct the Data-Definition object from it. Since VB/ISAM does not have the concept of Field Name, Vsam will assign default Field Names to each VB/ISAM field in the Format String. "Primary" is the default name assigned to the record Key and you can always use the "%0" form to access it. Each subsequent field is named using the following form:
Fn [A,R,X] [$,%,&,!,#,@] where:
F identifies a field name
n represents the assigned field number
A indicates the original field was a member of an array
C indicates the original field was a Compound index field
R indicates the original field was part of a repeated definition
X indicates the original field was indexed
Original Field Types:
$ = string
% = 16 bit integer
& = 32 bit integer
! = floating point single (32 bits)
# = floating point double (64 bits)
@ = currency (64 bits)
These default field names may be changed immediately by using the VsamExplorer application supplied with Vsam. For example: you can change "F1$" to "Name", or "Primary" to "ID". From then on you may access field 1 using the string "Name" in the VsamFetchField function. Again, you can always use the field identifier of "%1" to access the "Name" field.
Field numbers are assigned by Vsam as each field definition is created. While you can change the Field name, you cannot change the field number. The only time that a field number is released back to the free pool is when you delete a field and subsequently rebuild the dataset. This will physically purge all of the deleted fields from all records and return the associated field number to the free pool. Then the next field that you create will obtain that field number (actually the lowest free field number in the pool).
Once the data definition is created, the conversion process is complete - usually in less than a second. From then on, VB/ISAM can no longer access the dataset. Even though the dataset is considered converted, not all low level records are in the new form. As records are read by Vsam it will determine weather or not a record is in the old or new format and always convert it to the new form prior to returning it to an application. This way, if the client application writes the record, it will only be dealing with new format records. If you want to convert all records to the new form right away, you can use the VsamRebuild function. In general, this should not be necessary.
3. When you
delete a field definition in VsamEx, it is gone instantly. All subsequent reads
for that field in any record return a “not found” error code. How is this
While the Delete field function works immediately, the actual fields within records will remain in the low level DataSet and the following rules apply:
a VsamStoreField fail for the Primary Key field?
Remember when you
write a record with VsamPut
(after storing all fields except the primary) the Primary key is specified as a
parameter to the VsamPut
function. We have had discussions as to whether this should be wrapped
into the record but we chose to support legacy systems (VB/ISAM) that use the
concept that the Key is separate from the record, and thus passed as a separate
parameter. While the actual key data is stored in the same location as the
record, to be consistent, VsamStoreField
fails on the Primary key field.
Because of this, you can create a record in memory and clone it in the DataSet under different Primary Key names without changing the actual record (Just the Key). This is a good way to initialize a subset of records to the same set of field values.
5. Why do I need to set the Record Pointer to NULL or 0 the first time I call a VsamStoreField for a new record?
Record Pointers are pointers to allocated memory blocks that hold individual records. By setting the record pointer to 0 you signal to VsamStoreField to create a brand new record buffer with the stored field in it. You should use the record pointer returned from this call on subsequent calls to VsamStoreField to finish storing fields. Once the fields have been set, you can then call VsamPut.
If you call VsamStoreField without initializing the record pointer to 0, or by reading an older record with VsamGet, it will assume that it is a pointer to a previously allocated record buffer. If It tries to use this memory, it is likely that it is un-initialized memory or invalid memory and the Windows OS will get very unhappy and start to cry!!
Normally, you would read a record using VsamGet which would free an old record pointer (non-zero) and its associated memory and then allocate a new one for the new record. This is why you should always initialize a Record pointer to 0 the first time so it won't try to free garbage. On the other hand, it is not necessary to free the record pointer between reads as long as it was first allocated properly.
If you are creating multiple new records, you have to make sure that you call VsamStoreField for each field otherwise the old data will remain in the untouched fields. Alternatively, use the VsamFreeRec and set the record pointer to NULL (0) so that you do not generate memory leaks!
Except where we need to be thread safe or re-entrant, we use public global memory blocks to read and write records. This allows VsamEx to re-use and optimize the memory from record to record.
The reason we use this technique is because it allows the application software to manage multiple records in memory by simply saving the record pointer values (and their corresponding Keys). If you do this, don't forget to call VsamFreeRec to release each saved memory block. Remember that once you take control of the Record Pointer, and move the value to another variable, you should zero out the record pointer returned by the VsamEx function. If you don't do this, then the next time you go to get another record, the VsamEx function may release the old pointer and your saved value will no longer be valid!
6. Does VsamEx[treme] support multiple different record formats or Views within a single record ?
"One of the greatest features in the current VsamEx system is the unique ability to write just one routine to read (and one routine to write) ALL VsamEx files, regardless of the format of the file (because of the field types)."
" I can call a single routine, give it an argument of the fields that I want to read or write (ie: by field number: “%3,%4,%7” or by field name: “Name, address & Phone”), and the routine gives me exactly that -- I have about 20 files of various formats – This really simplifies things tremendously!"
"One of the nice byproducts of this is that the file locks can all be put in this single routine, and it works for all files. No other system that I know of can do this."
Actually, VsamEx supports sparse field technology that allows many different fields to be independently defined. Not all fields need be in each record. Therefore, the application can define "Views" of the DataSet that include different subsets of fields.
Fixed and Variable length Strings - Should
I use Variable length strings?
Fixed length strings are not necessary in modern basic implementations such as Visual Basic. They waste a lot more space and make coding and debugging harder. Certainly Data structure design and modification becomes more difficult. Anyway, both VB/ISAM & VsamEx[treme] store all strings as variable length fields in the records sent to the disk. So, even if you define a fixed length string, it is optimized on the disk by making it variable length.
In VB, all
parameters that are defined as strings for VB/ISAM are required to be variable
length. Some of the parameters that are passed to VB/ISAM functions will return
variable length string data, so if you pass a fixed length string as a
parameter to a VB/ISAM function, the results are unpredictable and may result
in a system fault of some kind.
On the other hand, fixed length strings are OK when used inside a Visual Basic User Defined Type's (UDT), as data elements, and that UDT is the record structure used to read and write data. But even here we discourage the use of fixed length strings. Furthermore, VB.NET does not support passing UDT's to OCX's or DLL's or using fixed length strings.
One of the things to remember is that when VsamEx or VB/ISAM scan through a Secondary list and you request XGET_DATA (the Default), the scanning routines jump back and forth between the Secondary area in the DataSet and the primary area. This is inefficient over a network!
To improve your overall performance, try using the "XNO_DATA" option while reading your keys. Once the user selects something, use the XGET_DATA to re-read the record. This will cause the file pointer to stay in the secondary and each subsequent XNEXT operation will be in memory (until a new group is required!). Of course, if the secondary is xref 0, that is the primary index and the only thing that the XNO_DATA will do is to save the record decode time. However, If your record structure is quite complex and you are using VB/ISAM, that can speed things up as well. Another performance device is to use the XNATIVE mode and only decode the field that you require. Again, when the UDT is complex this can save time. VsamEx[treme], on the other hand only supports the XNATIVE mode.
The VTRead function
in VTOOL is a different thing and has nothing to do with XNATIVE! XNATIVE
mode does not change the data stored in a VB/ISAM DataSet. It only
affects the way you look at the data. If a record is read using XNATIVE,
it is read from the DataSet and the data is returned as a pointer to
a data buffer containing the raw DataSet record. This saves the software
from decoding all fields it into a Type structure. This is always the way
VsamEx reads data. This is much faster even if you need to look at a lot of
fields. The key here is that you only unpack the field's that you
need. In writing the XNATIVE record, we do not perform the encode
function because what you are passing is a native VB/ISAM or VsamEx record.
The tradeoff is that, for larger records, this saves the decode/encode translation which may involve allocating memory and other overhead. Additionally, in Visual Basic, another language layer will translate this structure even further, adding to a potentially significant amount of time. This method of getting data directly into a structure is easy for the application programmer but may cost in performance.
VTRead, on the other hand, does some decoding and translating to return a record (not in native mode) but in a delimited field form. All binary data fields are translated into their string representations. This does not work very well for really complicated records, especially if they contain vertical bars "|". This read mode was intended only as a simple way to display the records in an unstructured way - more of a debugging tool. In order to reliably manipulate the data, you must use VmxGet with one of its options. Although there are cases where VTRead can be used (as long as you are aware of its limitations), it is still slower than the XNATIVE mode of VmxGet.
The maximum number
of Groups you can have in a VB/ISAM 4032 or 4016 DataSet is 16,380. If
each group is 32,768 bytes in size you can attain 530MB. The Group size
is determined at Create time. If you ran out of space at 32,758KB you
probably have a Group size of 2048.
There are two ways to change the group size. The first is to create a new DataSet (with the new group size and copy records from the old to the new. The second is to use our add-on product VTOOL for VB/ISAM or the VsamExplorer for VsamEx[treme]. It will rebuild your DataSet (at over 4MB per second) and allow you to specify a new group size. Of course, VsamEx[treme] will allow DataSet's to grow to 2.1GB because it supports up to 65,530 groups
Opportunistic locking in Windows fails to resolve caching conflicts with shared files. Microsoft has confirmed to us, that all systems that share files may encounter performance and corruption issues unless they turn off OpLocks:
EnableOplocks REG_DWORD 0 or 1
Default: 1 (TRUE)
UseOpportunisticLocking REG_DWORD 0 or 1
Default: 1 (TRUE)
PLEASE SET THESE
VALUES TO 0 (FALSE). If this key does not exist, the system assumes
a TRUE value for this setting!
Microsoft has confirmed that if files are opened in shared modes across the network and this key is TRUE, there may be instances of duplicate cached pages for the same file. This would cause multiple copies of the same records with different values to be cached, each to be written separately without conflict resolution. This is a very bad situation for any applications that share file access among multiple simultaneous users.
This table includes definitions and recommended actions for normal and extended diagnostic return codes from any VsamEx[treme] or VB/ISAM function call. Select the Hot Link above!
Software Source P.O. Box 23306, San Jose, California 95153 408-887-7367
- Email: firstname.lastname@example.org