<commit_before>/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/* Written by <NAME>, who has a shared copyright to this code */

/*  TODO: add caching - pre-read several index entries at once */

#define FT_CORE
#include "ftdefs.h"

/* search with boolean queries */

static double _wghts[11]=
{
  0.131687242798354,
  0.197530864197531,
  0.296296296296296,
  0.444444444444444,
  0.666666666666667,
  1.000000000000000,
  1.500000000000000,
  2.250000000000000,
  3.375000000000000,
  5.062500000000000,
  7.593750000000000};
static double *wghts=_wghts+5; /* wghts[i] = 1.5**i */

static double _nwghts[11]=
{
 -0.065843621399177,
 -0.098765432098766,
 -0.148148148148148,
 -0.222222222222222,
 -0.333333333333334,
 -0.500000000000000,
 -0.750000000000000,
 -1.125000000000000,
 -1.687500000000000,
 -2.531250000000000,
 -3.796875000000000};
static double *nwghts=_nwghts+5; /* nwghts[i] = -0.5*1.5**i */

#define FTB_FLAG_TRUNC 1
/* At most one of the following flags can be set */
#define FTB_FLAG_YES   2
#define FTB_FLAG_NO    4
#define FTB_FLAG_WONLY 8

typedef struct st_ftb_expr FTB_EXPR;
struct st_ftb_expr
{
  FTB_EXPR *up;
  uint      flags;
/* ^^^^^^^^^^^^^^^^^^ FTB_{EXPR,WORD} common section */
  my_off_t  docid[2];
  float     weight;
  float     cur_weight;
  byte     *quot, *qend;
  uint      yesses;               /* number of "yes" words matched */
  uint      nos;                  /* number of "no"  words matched */
  uint      ythresh;              /* number of "yes" words in expr */
  uint      yweaks;               /* number of "yes" words for scan only */
};

typedef struct st_ftb_word
{
  FTB_EXPR  *up;
  uint       flags;
/* ^^^^^^^^^^^^^^^^^^ FTB_{EXPR,WORD} common section */
  my_off_t   docid[2];             /* for index search and for scan */
  my_off_t   key_root;
  MI_KEYDEF *keyinfo;
  float      weight;
  uint       ndepth;
  uint       len;
  uchar      off;
  byte       word[1];
} FTB_WORD;

typedef struct st_ft_info
{
  struct _ft_vft *please;
  MI_INFO   *info;
  CHARSET_INFO *charset;
  FTB_EXPR  *root;
  FTB_WORD **list;
  MEM_ROOT   mem_root;
  QUEUE      queue;
  TREE       no_dupes;
  my_off_t   lastpos;
  uint       keynr;
  uchar      with_scan;
  enum { UNINITIALIZED, READY, INDEX_SEARCH, INDEX_DONE } state;
} FTB;

static int FTB_WORD_cmp(my_off_t *v, FTB_WORD *a, FTB_WORD *b)
{
  int i;

  /* if a==curdoc, take it as  a < b */
  if (v && a->docid[0] == *v)
    return -1;

  /* ORDER BY docid, ndepth DESC */
  i=CMP_NUM(a->docid[0], b->docid[0]);
  if (!i)
    i=CMP_NUM(b->ndepth,a->ndepth);
  return i;
}

static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b)
{
  /* ORDER BY word DESC, ndepth DESC */
  int i= mi_compare_text(cs, (uchar*) (*b)->word+1,(*b)->len-1,
                             (uchar*) (*a)->word+1,(*a)->len-1,0,0);
  if (!i)
    i=CMP_NUM((*b)->ndepth,(*a)->ndepth);
  return i;
}

static void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
                      FTB_EXPR *up, uint depth)
{
  byte        res;
  FTB_PARAM   param;
  FT_WORD     w;
  FTB_WORD   *ftbw;
  FTB_EXPR   *ftbe;
  uint  extra=HA_FT_WLEN+ftb->info->s->rec_reflength; /* just a shortcut */

  if (ftb->state != UNINITIALIZED)
    return;

  param.prev=' ';
  param.quot=up->quot;
  while ((res=ft_get_word(ftb->charset,start,end,&w,&param)))
  {
    int   r=param.plusminus;
    float weight= (float) (param.pmsign ? nwghts : wghts)[(r>5)?5:((r<-5)?-5:r)];
    switch (res) {
      case 1: /* word found */
        ftbw=(FTB_WORD *)alloc_root(&ftb->mem_root,
                                    sizeof(FTB_WORD) +
                                    (param.trunc ? MI_MAX_KEY_BUFF :
                                     w.len+extra));
        ftbw->len=w.len+1;<commit_msg>allocate a buffer large enough for a longer matching string<commit_after>/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/* Written by <NAME>, who has a shared copyright to this code */

/*  TODO: add caching - pre-read several index entries at once */

#define FT_CORE
#include "ftdefs.h"

/* search with boolean queries */

static double _wghts[11]=
{
  0.131687242798354,
  0.197530864197531,
  0.296296296296296,
  0.444444444444444,
  0.666666666666667,
  1.000000000000000,
  1.500000000000000,
  2.250000000000000,
  3.375000000000000,
  5.062500000000000,
  7.593750000000000};
static double *wghts=_wghts+5; /* wghts[i] = 1.5**i */

static double _nwghts[11]=
{
 -0.065843621399177,
 -0.098765432098766,
 -0.148148148148148,
 -0.222222222222222,
 -0.333333333333334,
 -0.500000000000000,
 -0.750000000000000,
 -1.125000000000000,
 -1.687500000000000,
 -2.531250000000000,
 -3.796875000000000};
static double *nwghts=_nwghts+5; /* nwghts[i] = -0.5*1.5**i */

#define FTB_FLAG_TRUNC 1
/* At most one of the following flags can be set */
#define FTB_FLAG_YES   2
#define FTB_FLAG_NO    4
#define FTB_FLAG_WONLY 8

typedef struct st_ftb_expr FTB_EXPR;
struct st_ftb_expr
{
  FTB_EXPR *up;
  uint      flags;
/* ^^^^^^^^^^^^^^^^^^ FTB_{EXPR,WORD} common section */
  my_off_t  docid[2];
  float     weight;
  float     cur_weight;
  byte     *quot, *qend;
  uint      yesses;               /* number of "yes" words matched */
  uint      nos;                  /* number of "no"  words matched */
  uint      ythresh;              /* number of "yes" words in expr */
  uint      yweaks;               /* number of "yes" words for scan only */
};

typedef struct st_ftb_word
{
  FTB_EXPR  *up;
  uint       flags;
/* ^^^^^^^^^^^^^^^^^^ FTB_{EXPR,WORD} common section */
  my_off_t   docid[2];             /* for index search and for scan */
  my_off_t   key_root;
  MI_KEYDEF *keyinfo;
  float      weight;
  uint       ndepth;
  uint       len;
  uchar      off;
  byte       word[1];
} FTB_WORD;

typedef struct st_ft_info
{
  struct _ft_vft *please;
  MI_INFO   *info;
  CHARSET_INFO *charset;
  FTB_EXPR  *root;
  FTB_WORD **list;
  MEM_ROOT   mem_root;
  QUEUE      queue;
  TREE       no_dupes;
  my_off_t   lastpos;
  uint       keynr;
  uchar      with_scan;
  enum { UNINITIALIZED, READY, INDEX_SEARCH, INDEX_DONE } state;
} FTB;

static int FTB_WORD_cmp(my_off_t *v, FTB_WORD *a, FTB_WORD *b)
{
  int i;

  /* if a==curdoc, take it as  a < b */
  if (v && a->docid[0] == *v)
    return -1;

  /* ORDER BY docid, ndepth DESC */
  i=CMP_NUM(a->docid[0], b->docid[0]);
  if (!i)
    i=CMP_NUM(b->ndepth,a->ndepth);
  return i;
}

static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b)
{
  /* ORDER BY word DESC, ndepth DESC */
  int i= mi_compare_text(cs, (uchar*) (*b)->word+1,(*b)->len-1,
                             (uchar*) (*a)->word+1,(*a)->len-1,0,0);
  if (!i)
    i=CMP_NUM((*b)->ndepth,(*a)->ndepth);
  return i;
}

static void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
                      FTB_EXPR *up, uint depth)
{
  byte        res;
  FTB_PARAM   param;
  FT_WORD     w;
  FTB_WORD   *ftbw;
  FTB_EXPR   *ftbe;
  uint  extra=HA_FT_WLEN+ftb->info->s->rec_reflength; /* just a shortcut */

  if (ftb->state != UNINITIALIZED)
    return;

  param.prev=' ';
  param.quot=up->quot;
  while ((res=ft_get_word(ftb->charset,start,end,&w,&param)))
  {
    int   r=param.plusminus;
    float weight= (float) (param.pmsign ? nwghts : wghts)[(r>5)?5:((r<-5)?-5:r)];
    switch (res) {
      case 1: /* word found */
        ftbw=(FTB_WORD *)alloc_root(&ftb->mem_root,
                                    sizeof(FTB_WORD) +
                                    (param.trunc ? MI_MAX_KEY_BUFF :
                                     w.len*ftb->charset->mbmaxlen+extra));
        ftbw->len=w.len+1;
{'fraction_non_alphanumeric': 0.12523405661416456, 'fraction_numerical': 0.08943716268311488, 'mean_word_length': 2.6290967226219024, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 32, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3365326', 'n_tokens_mistral': 3953, 'n_tokens_neox': 3365, 'n_words': 906}