Hi,

in the beginning I was going to write a private email to Przemek and ask about CDX detail, but more deep test gave me an answer.

The problem of the customers was that sometimes browse does not show records (in scoped alias), but records for sure exist in database. We found that ORDKEYCOUNT() return zero but scope is not empty. The problem of ADS RDD is that it does not check return values of ADS API functions in many places, for exmaple, in processing of DBOI_KEYCOUNT. Here AdsGetRecordCount() return error 7022.

Advantage Error Guide:
----------------------
7022 Maximum index levels

Problem: The current index is unbalanced. This problem is most likely to occur when using very long index keys and new keys are being added to the index. This error could also occur if the index is corrupt.

Solution: Reindex the file. The reindexed file will be built using the minimum number of levels. This will speed up all future operations using the index. If this does not resolve the problem, reindex with a larger page size (see Index Page Size, or see the API AdsReindex61 in the Advantage Client Engine Help or the method AdsIndexPageSize in the Advantage TDataSet Descendant Help). With a larger index page size, more keys will be stored in each page and will thus reduce the number of levels required. For specific equations showing the correlation between key and page size, see Index Key Size and Page Size Relationships.
----------------------

Unfortunately CDX page size is fixed 512 and can not be changed. I have a database table from our customers. It has 50342 records only and index key length is 133 bytes. I have a feeling this is a too small limits for real life a database. Documented maximum key length is 240 bytes.

I had an idea that index tree level count can be limited by CDX structure, but after I've wrote a self contained test and compared ADSCDX and DBFCDX results, I understand it is a limit of ADS implementation. Both my real life key length 133, and a maximum documented key length 240 was tested (see test source below):
  RDD: ADSCDX KeyLen:    240 LASTREC():   6058 ORDKEYCOUNT():     0
  RDD: ADSCDX KeyLen:    133 LASTREC(): 250052 ORDKEYCOUNT():     0
So, using a maximum documented key length (240 bytes) ADS can manage tables having only(!) 6058 records. The same results are for both 8.1 and 9.1 version of ADS.

(512-some_header) / (240 + pointer_size) = 2 keys per page
log(6058)/log(2+1)~= 7,927 ~= 8

(512-some_header) / (133 + pointer_size) = 3 keys per page
log(250052)/log(3+1)~= 8,966 ~= 9

So, maximum index tree level in ADS is 8, or 9, or a little more, if index is unbalanced. Perhaps ADS uses a fixed length array to store pages in index navigation operations. I've not tested yet, if DBSKIP() or DBSEEK() has also the same limits, or it is a problem of ORDKEYCOUNT() only.

I was unable to find a index level limit in Harbour's DBFCDX driver using the test.


Regards,
Mindaugas


---------------------------
#include "ads.ch"

EXTERNAL ADS, DBFCDX
ANNOUNCE RDDSYS

#define KEYLEN 240

FUNC main()
  ADSSetFileType(ADS_CDX)
  ADSSetServerType(ADS_REMOTE_SERVER)
  ? "Press ESC to cancel"
  test("ADSCDX", "\\server\share\test176", KEYLEN)
  test("DBFCDX", "test176", KEYLEN)
RETURN 0

PROC test(cRDD, cPath, nKeyLen)
LOCAL nI, nJ
  DBCREATE(cPath, {{"KEY", "C", nKeyLen, 0}}, cRDD, .T., "test")
  ORDCREATE(cPath, "key", "KEY")
  ? "Testing ", cRDD, "..."
  FOR nI := 1 TO 1000
     FOR nJ := 1 TO 1000
       DBAPPEND()
       FIELD->KEY := REPLICATE(HB_MD5(STR(nI) + STR(nJ)), 8)
     NEXT
     IF ORDKEYCOUNT() != LASTREC()
? "RDD:", cRDD, "KeyLen:", nKeyLen, "LASTREC():", LASTREC(), "ORDKEYCOUNT():", ORDKEYCOUNT()
       EXIT
     ENDIF
     ?? nI
     IF INKEY() == 27
       EXIT
     ENDIF
  NEXT
  DBCLOSEAREA()
RETURN

_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to