<commit_before>/*
 * spillbuf-test.c : test the spill buffer code
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

#include "svn_types.h"

#include "private/svn_subr_private.h"

#include "../svn_test.h"


static const char basic_data[] = ("abcdefghijklmnopqrstuvwxyz"
                                  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                                  "0123456789");


static svn_error_t *
test_spillbuf_basic(apr_pool_t *pool)
{
  svn_spillbuf_t *buf = svn_spillbuf_create(
                          sizeof(basic_data) /* blocksize */,
                          10 * sizeof(basic_data) /* maxsize */,
                          pool);
  int i;

  /* It starts empty.  */
  SVN_TEST_ASSERT(svn_spillbuf_is_empty(buf));

  /* Place enough data into the buffer to cause a spill to disk.  */
  for (i = 20; i--; )
    SVN_ERR(svn_spillbuf_write(buf, basic_data, sizeof(basic_data), pool));

  /* And now has content.  */
  SVN_TEST_ASSERT(!svn_spillbuf_is_empty(buf));

  while (TRUE)
    {
      const char *readptr;
      apr_size_t readlen;

      SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
      if (readptr == NULL)
        break;

      /* We happen to know that the spill buffer reads data in lengths
         of BLOCKSIZE.  */
      SVN_TEST_ASSERT(readlen == sizeof(basic_data));

      /* And it should match each block of data we put in.  */
      SVN_TEST_ASSERT(memcmp(readptr, basic_data, readlen) == 0);
    }

  SVN_TEST_ASSERT(svn_spillbuf_is_empty(buf));

  return SVN_NO_ERROR;
}


static svn_error_t *
test_spillbuf_file(apr_pool_t *pool)
{
  svn_spillbuf_t *buf = svn_spillbuf_create(
                          sizeof(basic_data) + 2 /* blocksize */,
                          2 * sizeof(basic_data) /* maxsize */,
                          pool);
  int i;
  const char *readptr;
  apr_size_t readlen;
  int cur_index;

  /* Place enough data into the buffer to cause a spill to disk. Note that
     we are writing data that is *smaller* than the blocksize.  */
  for (i = 7; i--; )
    SVN_ERR(svn_spillbuf_write(buf, basic_data, sizeof(basic_data), pool));

  /* The first three reads will be in-memory blocks, so they will match
     what we wrote into the spill buffer.  */
  SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
  SVN_TEST_ASSERT(readptr != NULL);
  SVN_TEST_ASSERT(readlen == sizeof(basic_data));
  SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
  SVN_TEST_ASSERT(readptr != NULL);
  SVN_TEST_ASSERT(readlen == sizeof(basic_data));
  SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
  SVN_TEST_ASSERT(readptr != NULL);
  SVN_TEST_ASSERT(readlen == sizeof(basic_data));

  /* Current index into basic_data[] that we compare against.  */
  cur_index = 0;

  while (TRUE)
    {
      /* This will read more bytes (from the spill file into a temporary
         in-memory block) than the blocks of data that we wrote. This makes
         it trickier to verify that the right data is being returned.  */
      SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
      if (readptr == NULL)
        break;

      while (TRUE)
        {
          apr_size_t amt;

          /* Compute the slice of basic_data that we will compare against,
             given the readlen and cur_index.  */
          if (cur_index + readlen >= sizeof(basic_data))
            amt = sizeof(basic_data) - cur_index;
          else
            amt = readlen;
          SVN_TEST_ASSERT(memcmp(readptr, &basic_data[cur_index], amt) == 0);
          if ((cur_index += amt) == sizeof(basic_data))
            cur_index = 0;
          if ((readlen -= amt) == 0)
            break;
          readptr += amt;
        }
    }

  SVN_TEST_ASSERT(svn_spillbuf_is_empty(buf));

  return SVN_NO_ERROR;
}


/* The test table.  */
struct svn_test_descriptor_t test_funcs[] =
  {
    SVN_TEST_NULL,
    SVN_TEST_PASS2(test_spillbuf_basic, "basic spill buffer test"),
    SVN_TEST_PASS2(test_spillbuf_file, "spill buffer file test"),
    SVN_TEST_NULL
  };<commit_msg>Add a test of interleaving reads and writes.<commit_after>/*
 * spillbuf-test.c : test the spill buffer code
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

#include "svn_types.h"

#include "private/svn_subr_private.h"

#include "../svn_test.h"


static const char basic_data[] = ("abcdefghijklmnopqrstuvwxyz"
                                  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                                  "0123456789");


static svn_error_t *
test_spillbuf_basic(apr_pool_t *pool)
{
  svn_spillbuf_t *buf = svn_spillbuf_create(
                          sizeof(basic_data) /* blocksize */,
                          10 * sizeof(basic_data) /* maxsize */,
                          pool);
  int i;

  /* It starts empty.  */
  SVN_TEST_ASSERT(svn_spillbuf_is_empty(buf));

  /* Place enough data into the buffer to cause a spill to disk.  */
  for (i = 20; i--; )
    SVN_ERR(svn_spillbuf_write(buf, basic_data, sizeof(basic_data), pool));

  /* And now has content.  */
  SVN_TEST_ASSERT(!svn_spillbuf_is_empty(buf));

  while (TRUE)
    {
      const char *readptr;
      apr_size_t readlen;

      SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
      if (readptr == NULL)
        break;

      /* We happen to know that the spill buffer reads data in lengths
         of BLOCKSIZE.  */
      SVN_TEST_ASSERT(readlen == sizeof(basic_data));

      /* And it should match each block of data we put in.  */
      SVN_TEST_ASSERT(memcmp(readptr, basic_data, readlen) == 0);
    }

  SVN_TEST_ASSERT(svn_spillbuf_is_empty(buf));

  return SVN_NO_ERROR;
}


static svn_error_t *
test_spillbuf_file(apr_pool_t *pool)
{
  svn_spillbuf_t *buf = svn_spillbuf_create(
                          sizeof(basic_data) + 2 /* blocksize */,
                          2 * sizeof(basic_data) /* maxsize */,
                          pool);
  int i;
  const char *readptr;
  apr_size_t readlen;
  int cur_index;

  /* Place enough data into the buffer to cause a spill to disk. Note that
     we are writing data that is *smaller* than the blocksize.  */
  for (i = 7; i--; )
    SVN_ERR(svn_spillbuf_write(buf, basic_data, sizeof(basic_data), pool));

  /* The first three reads will be in-memory blocks, so they will match
     what we wrote into the spill buffer.  */
  SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
  SVN_TEST_ASSERT(readptr != NULL);
  SVN_TEST_ASSERT(readlen == sizeof(basic_data));
  SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
  SVN_TEST_ASSERT(readptr != NULL);
  SVN_TEST_ASSERT(readlen == sizeof(basic_data));
  SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
  SVN_TEST_ASSERT(readptr != NULL);
  SVN_TEST_ASSERT(readlen == sizeof(basic_data));

  /* Current index into basic_data[] that we compare against.  */
  cur_index = 0;

  while (TRUE)
    {
      /* This will read more bytes (from the spill file into a temporary
         in-memory block) than the blocks of data that we wrote. This makes
         it trickier to verify that the right data is being returned.  */
      SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
      if (readptr == NULL)
        break;

      while (TRUE)
        {
          apr_size_t amt;

          /* Compute the slice of basic_data that we will compare against,
             given the readlen and cur_index.  */
          if (cur_index + readlen >= sizeof(basic_data))
            amt = sizeof(basic_data) - cur_index;
          else
            amt = readlen;
          SVN_TEST_ASSERT(memcmp(readptr, &basic_data[cur_index], amt) == 0);
          if ((cur_index += amt) == sizeof(basic_data))
            cur_index = 0;
          if ((readlen -= amt) == 0)
            break;
          readptr += amt;
        }
    }

  SVN_TEST_ASSERT(svn_spillbuf_is_empty(buf));

  return SVN_NO_ERROR;
}


static svn_error_t *
test_spillbuf_interleaving(apr_pool_t *pool)
{
  svn_spillbuf_t *buf = svn_spillbuf_create(8 /* blocksize */,
                                            11 /* maxsize */,
                                            pool);
  const char *readptr;
  apr_size_t readlen;

  SVN_ERR(svn_spillbuf_write(buf, "abcdef", 6, pool));
  SVN_ERR(svn_spillbuf_write(buf, "ghijkl", 6, pool));
  /* now: two blocks of 6 bytes each  */

  SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
  SVN_TEST_ASSERT(readptr != NULL
                  && readlen == 6
                  && memcmp(readptr, "abcdef", 6) == 0);
  /* now: one block of 6 bytes  */

  SVN_ERR(svn_spillbuf_write(buf, "mnopqr", 6, pool));
  /* now: two blocks of 6 bytes each  */

  SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
  SVN_TEST_ASSERT(readptr != NULL
                  && readlen == 6
                  && memcmp(readptr, "ghijkl", 6) == 0);
  /* now: one block of 6 bytes  */

  SVN_ERR(svn_spillbuf_write(buf, "stuvwx", 6, pool));
  SVN_ERR(svn_spillbuf_write(buf, "ABCDEF", 6, pool));
  SVN_ERR(svn_spillbuf_write(buf, "GHIJKL", 6, pool));
  /* now: two blocks of 6 bytes each, and 12 bytes spilled to a file  */

  SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
  SVN_TEST_ASSERT(readptr != NULL
                  && readlen == 6
                  && memcmp(readptr, "mnopqr", 6) == 0);
  SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
  SVN_TEST_ASSERT(readptr != NULL
                  && readlen == 6
                  && memcmp(readptr, "stuvwx", 6) == 0);
  SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
  SVN_TEST_ASSERT(readptr != NULL
                  && readlen == 8
                  && memcmp(readptr, "ABCDEFGH", 8) == 0);
  SVN_ERR(svn_spillbuf_read(&readptr, &readlen, buf, pool));
  SVN_TEST_ASSERT(readptr != NULL
                  && readlen == 4
                  && memcmp(readptr, "IJKL", 4) == 0);

  return SVN_NO_ERROR;
}


/* The test table.  */
struct svn_test_descriptor_t test_funcs[] =
  {
    SVN_TEST_NULL,
    SVN_TEST_PASS2(test_spillbuf_basic, "basic spill buffer test"),
    SVN_TEST_PASS2(test_spillbuf_file, "spill buffer file test"),
    SVN_TEST_PASS2(test_spillbuf_interleaving,
                   "interleaving reads and writes"),
    SVN_TEST_NULL
  };
{'fraction_non_alphanumeric': 0.12430595839893925, 'fraction_numerical': 0.007541228142868982, 'mean_word_length': 2.638227313837805, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6950840', 'n_tokens_mistral': 4069, 'n_tokens_neox': 3892, 'n_words': 1056}