/ Check-in [a1747086]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Minor commenting and stylistic changes only.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | fts4-incr-merge
Files: files | file ages | folders
SHA1:a1747086c5e0c152fcf4bd9fa80a61b6f03f4a94
User & Date: drh 2012-03-09 12:52:43
Context
2012-03-13
19:56
Fix some bugs in the incremental merge code. Some remain. check-in: bff21683 user: dan tags: fts4-incr-merge
2012-03-09
12:52
Minor commenting and stylistic changes only. check-in: a1747086 user: drh tags: fts4-incr-merge
2012-03-08
18:39
Add the 'merge=?,?' command to fts4. This still needs some work. check-in: 741b8f89 user: dan tags: fts4-incr-merge
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/fts3/fts3_write.c.

4128
4129
4130
4131
4132
4133
4134









4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
....
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
....
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203





4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
      rc = fts3TruncateSegment(p, iAbsLevel, pSeg->iIdx, zTerm, nTerm);
    }
  }

  return rc;
}










static int fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
  int rc = SQLITE_OK;             /* Return code */
  int nRem = nMerge;

  assert( nMin>=2 );

  while( rc==SQLITE_OK && nRem>0 ){
    sqlite3_int64 iAbsLevel;        /* Absolute level number to work on */
    sqlite3_stmt *pFindLevel = 0;   /* SQL used to determine iAbsLevel */
    Fts3MultiSegReader csr;         /* Cursor used to read input data */
................................................................................
      return sqlite3_reset(pFindLevel);
    }
    iAbsLevel = sqlite3_column_int64(pFindLevel, 0);
    rc = sqlite3_reset(pFindLevel);
    if( rc!=SQLITE_OK ) return rc;

    /* Open a cursor to iterate through the contents of indexes 0 and 1 of
     ** the selected absolute level. */
    rc = fts3IncrmergeCsr(p, iAbsLevel, &csr);
    if( rc!=SQLITE_OK ) return rc;
    memset(&filter, 0, sizeof(Fts3SegFilter));
    filter.flags = FTS3_SEGMENT_REQUIRE_POS;

    rc = sqlite3Fts3SegReaderStart(p, &csr, &filter);
    assert( rc!=SQLITE_ABORT );
    if( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){
      rc = fts3IncrmergeWriter(p, iAbsLevel, csr.zTerm, csr.nTerm, &writer);
    assert( rc!=SQLITE_ABORT );
      if( rc==SQLITE_OK ){
        do {
          rc = fts3IncrmergeAppend(p, &writer, &csr);
    assert( rc!=SQLITE_ABORT );
          if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, &csr);
    assert( rc!=SQLITE_ABORT );
          if( writer.nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK;
        }while( rc==SQLITE_ROW );
      }
    }
    assert( rc!=SQLITE_ABORT );
    fts3IncrmergeRelease(p, &writer, &rc);
    nRem -= (1 + writer.nWork);
................................................................................

    sqlite3Fts3SegReaderFinish(&csr);
  }

  return rc;
}

static int fts3_isdigit(char c){
  return (c>='0' && c<='9');
}






static int fts3DoIncrmerge(Fts3Table *p, const char *zParam){
  int rc;
  int nMin = (FTS3_MERGE_COUNT / 2);
  int nMerge = 0;
  const char *z = zParam;

  /* Read the first integer value */
  for(z=zParam; fts3_isdigit(z[0]); z++){
    nMerge = nMerge * 10 + (z[0] - '0');
  }

  /* If the first integer value is followed by a ',',  read the second
  ** integer value. */
  if( z[0]==',' && z[1]!='\0' ){
    z++;
    nMin = 0;
    while( fts3_isdigit(z[0]) ){
      nMin = nMin * 10 + (z[0] - '0');
      z++;
    }
  }

  if( z[0]!='\0' ) return SQLITE_ERROR;
  if( nMin<2 ) nMin = 2;







>
>
>
>
>
>
>
>
>


|







 







|









|



|

|







 







|
|
|
|
>
>
>
>
>







|








|







4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
....
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
....
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
      rc = fts3TruncateSegment(p, iAbsLevel, pSeg->iIdx, zTerm, nTerm);
    }
  }

  return rc;
}

/*
** Attempt an incremental merge that writes nMerge leaf pages.
**
** Incremental merges happen two segments at a time.  The two
** segments to be merged are the two oldest segments (the ones with
** the smallest index) in the highest level that has at least
** nMin segments.  Multiple segment pair merges might occur in
** an attempt to write the quota of nMerge leaf pages.
*/
static int fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
  int rc = SQLITE_OK;             /* Return code */
  int nRem = nMerge;              /* Number of leaf pages yet to  be written */

  assert( nMin>=2 );

  while( rc==SQLITE_OK && nRem>0 ){
    sqlite3_int64 iAbsLevel;        /* Absolute level number to work on */
    sqlite3_stmt *pFindLevel = 0;   /* SQL used to determine iAbsLevel */
    Fts3MultiSegReader csr;         /* Cursor used to read input data */
................................................................................
      return sqlite3_reset(pFindLevel);
    }
    iAbsLevel = sqlite3_column_int64(pFindLevel, 0);
    rc = sqlite3_reset(pFindLevel);
    if( rc!=SQLITE_OK ) return rc;

    /* Open a cursor to iterate through the contents of indexes 0 and 1 of
    ** the selected absolute level. */
    rc = fts3IncrmergeCsr(p, iAbsLevel, &csr);
    if( rc!=SQLITE_OK ) return rc;
    memset(&filter, 0, sizeof(Fts3SegFilter));
    filter.flags = FTS3_SEGMENT_REQUIRE_POS;

    rc = sqlite3Fts3SegReaderStart(p, &csr, &filter);
    assert( rc!=SQLITE_ABORT );
    if( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){
      rc = fts3IncrmergeWriter(p, iAbsLevel, csr.zTerm, csr.nTerm, &writer);
      assert( rc!=SQLITE_ABORT );
      if( rc==SQLITE_OK ){
        do {
          rc = fts3IncrmergeAppend(p, &writer, &csr);
          assert( rc!=SQLITE_ABORT );
          if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, &csr);
          assert( rc!=SQLITE_ABORT );
          if( writer.nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK;
        }while( rc==SQLITE_ROW );
      }
    }
    assert( rc!=SQLITE_ABORT );
    fts3IncrmergeRelease(p, &writer, &rc);
    nRem -= (1 + writer.nWork);
................................................................................

    sqlite3Fts3SegReaderFinish(&csr);
  }

  return rc;
}

/*
** Process statements of the form:
**
**    INSERT INTO table(table) VALUES('merge=A,B');
**
** A and B are integers that decode to be the number of leaf pages
** written for the merge, and the minimum number of segments on a level
** before it will be selected for a merge, respectively.
*/
static int fts3DoIncrmerge(Fts3Table *p, const char *zParam){
  int rc;
  int nMin = (FTS3_MERGE_COUNT / 2);
  int nMerge = 0;
  const char *z = zParam;

  /* Read the first integer value */
  for(z=zParam; z[0]>='0' && z[0]<='9'; z++){
    nMerge = nMerge * 10 + (z[0] - '0');
  }

  /* If the first integer value is followed by a ',',  read the second
  ** integer value. */
  if( z[0]==',' && z[1]!='\0' ){
    z++;
    nMin = 0;
    while( z[0]>='0' && z[0]<='9' ){
      nMin = nMin * 10 + (z[0] - '0');
      z++;
    }
  }

  if( z[0]!='\0' ) return SQLITE_ERROR;
  if( nMin<2 ) nMin = 2;