>Recno() is not bad as speeds go - remember setting relation not via index, but recno() in child table back in 386/486 days?
That's the "thing I learned about VFP" for today ;) It's been a long time since I used SET RELATION (last century, I believe). I never used the numeric variation, I always indexed the child table.
>Could give you speedups between 30 and 55% when you ditched the index file ;-)
>
>Depends a lot on how you need the result (table) and what processing follows.
>A variation of the theme would be to not create a result cursor, but to delete the existing numbers/records/recno() from the alltable and to recall all before each run.
Another clever idea!
>As each deletion mark is also only 1 char wide, much less write traffic to the physical medium. Deleting on a table of integers incurs the same amount of write traffic as on the recno() of single chars (both non-null), but again the basic table size for int columns is larger - which translates back into more head movement - bad on traditional disk, less worrysome on SSD as random IO has less perf problems there.
>
>Also more records per physical sector/cluster in the non-int case, and I guess that would translate perhaps into less physical writes triggered via the OS, but that is a gut guess - although the total # of sectors written probably is less in the char/recno()-table setup ;-))
>
> Thinking on more basic computerese building blocks is today not needed any more ;-)
Exactly. The point about less I/O due to deletemark vs actual deletion is valid regardless of environment. But the other stuff... these days pretty much all my VFP work is in VMs. The host typically has a lot of RAM and write caching enabled so the nuts & bolts of getting bytes to/from persistent storage are pretty well hidden.
>>Clever - but how would it work in practice? Is it possible to avoid RECNO() calls in the final SELECT - SQL?
>>
>>>Going all out to minimize space, a table of char[1] indexed on recno() and selecting the same would allow much larger ranges to fit into a cache ;-))
>>>
>>>>Definitely. A DBF + CDX of 10,000 integers totals about 95KB, which will fit in the cache of many modern CPUs (L2 or L3, if not L1) so it could be a big performance win in a recurring-calls scenario.
>>>>
>>>>>The OP reads to me that this is a recurring requirement, so I'd exchange space for time and create AllLarge as pre-indexed table and query the range established by min/max via where ;-))
>>>>>
>>>>>>>The Range may be Between 1 to 10000 and it is not necessary that 1 will in the top or 10000 will be at the bottom of the cursor.
>>>>>>>I need Missing Figures in a Cursor (Difference in Numbers=1)
>>>>>>
>>>>>>There is a way to do it via SQL - maybe not the fastest, but relatively simple and maintainable:
>>>>>>
>>>>>>* Assume your cursor with random values has an alias RandomVals
>>>>>>LOCAL ;
>>>>>> lnMinVal ;
>>>>>> , lnMaxVal ;
>>>>>> , lnIx
>>>>>>
>>>>>>* Get lowest and highest values:
>>>>>>* Option 1: index RandomVals:
>>>>>>SELECT RandomVals
>>>>>>INDEX ON fObjectNo TAG fObjectNo
>>>>>>
>>>>>>GO TOP
>>>>>>m.lnMinVal = RandomVals.fObjectNo
>>>>>
>>>>>
>>>>>>GO BOTTOM
>>>>>>m.lnMaxVal = RandomVals.fObjectNo
>>>>>>
>>>>>>* Option 2: don't want to index RandomVals:
>>>>>>*!* CALCULATE ;
>>>>>>*!* MIN( fObjectNo ) ;
>>>>>>*!* , MAX( fObjectNo ) ;
>>>>>>*!* TO ;
>>>>>>*!* m.lnMinVal ;
>>>>>>*!* , m.lnMaxVal ;
>>>>>>*!* IN RandomVals
>>>>>>
>>>>>>* Create another cursor with all possible values, both present and missing:
>>>>>>CREATE CURSOR AllVals ( iVal I )
>>>>>>
>>>>>>* Populate the cursor with all possible values between m.lnMinVal and m.lnMaxVal
>>>>>>FOR m.lnIx = m.lnMinVal TO m.lnMaxVal STEP 1
>>>>>> INSERT INTO AllVals ( iVal ) VALUES ( m.lnIx )
>>>>>>
>>>>>>ENDFOR
>>>>>>
>>>>>>* Optional - index AllVals to help speed up the final SELECT - SQL:
>>>>>>SELECT AllVals
>>>>>>INDEX ON iVal TAG iVal
>>>>>>
>>>>>>* Get missing values:
>>>>>>SELECT ;
>>>>>> iVal ;
>>>>>> FROM AllVals ;
>>>>>> WHERE iVal NOT IN ;
>>>>>> ( SELECT fObjectNo FROM RandomVals ) ;
>>>>>> INTO CURSOR MissingVals ;
>>>>>> ORDER BY iVal
>>>>>>
>>>>>>* Cleanup:
>>>>>>USE IN SELECT( "AllVals" )
>>>>>>
Regards. Al
"Violence is the last refuge of the incompetent." -- Isaac Asimov
"Never let your sense of morals prevent you from doing what is right." -- Isaac Asimov
Neither a despot, nor a doormat, be
Every app wants to be a database app when it grows up