Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Index Corrupted Programmatically
Message
From
25/11/1998 16:28:55
 
 
To
All
General information
Forum:
Visual FoxPro
Category:
Other
Title:
Index Corrupted Programmatically
Miscellaneous
Thread ID:
00161606
Message ID:
00161606
Views:
58
VFP 5.0a SP3

Until today, I believed that an index could only be corrupted by exiting from a running program in a rude way (Ctrl-Alt-Del, pull the plug, etc.) but today I have corrupted one of two indexes in a CDX file.

Because of some index corruption in the field, I wrote a program to test some code I had that is supposed to recycle records in a table. The test program rapidly adds 3000 records to a table by either adding a new record (INSERT INTO) or by recycling a record (REPLACE ... WITH ...) that has my lDeleted field set to .T.

When I ran the test program, everything worked fine. My real world application, though, has many processes (exe’s) running the same code, and the table updates will regularly have to deal with contention issues. To simulate this, I ran 10 copies of the test program at the same time. At the end, one of the two indexes in the target table “MatchQue” was corrupted. Interestingly, the corrupted index was not the one that I was using to find records suitable for deletion, but rather, one that was not referenced in the test.

What can I do to stop the index corruption my index?

The test program calls GenMatchEvent() 3000 times - see below. On 80% of the cycles, the test program sets MatchQue.lDeteted to .T. to simulate the real world where the records get "deleted".

Bob
*////////////////////////////////////////////////////////////
function GenMatchEvent
LOCAL liRecno, lnOldSelect, lcOldOrder

lnOldSelect	= select(0)
lcOldOrder	= order()
SELECT MatchQue

liRecno = RecycleIflDeleted()  && Returns RecNo to Recycle,
                               && or –1 if no recyclable records
                               && are available
IF liRecno = -1
  INSERT into MatchQue (icallnum,cfleet,cvehicle,cMatchtype,tRefTime) ;
         values (tiID,tcFleet,tcID,tcType,ttRefTime)
ELSE
  BLANK
  REPLACE MatchQue.icallnum   with tiID   ,;
          MatchQue.cfleet     with tcFleet,;
          MatchQue.cvehicle   with tcID   ,;
          MatchQue.cMatchtype with tcType ,;
          MatchQue.tRefTime   with ttRefTime in "MatchQue"
  unlock record liRecno
ENDIF

SELECT (lnOldSelect)     && Restore original 
SET order to &lcOldOrder && Restore original 
 

*////////////////////////////////////////////////////////////
function RecycleIflDeleted()
local lnReturnedRecNo, lnOldSelect, lcOldOrder, lnOldReprocess

tcTableName = alias()
lnOldSelect	    = select(0)
lcOldOrder	    = order()
lnOldReprocess  = set("reprocess")

select (tcTableName)
set order     to MyDeleted  && indexed on MatchQue.lDeleted
set reprocess to 1

lnReturnedRecNo = -1  && Initialize as Recyclable (lDeleted = .t.)
                      && record not found
if seek(.t.)
  do while !eof() and lDeleted
    if rlock()
      if lDeleted                 && Didn't changed while getting
        lnReturnedRecNo = recno() && the lock so we will send back 
        exit                      && it's record # for recycling.
      else
        unlock record recno()     && unlock JUST this one
      endif  
    endif
  	 	
    skip
  enddo
endif

select            (lnOldSelect)
set order      to &lcOldOrder
set reprocess  to lnOldReprocess

return lnReturnedRecNo
Next
Reply
Map
View

Click here to load this message in the networking platform