// Copyright 2011 Google Inc.
//
// Licensed 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.
//
// Author: jhoch@google.com (Jason Hoch)

#include "pagespeed/kernel/sharedmem/shared_dynamic_string_map_test_base.h"

#include <cmath>
#include <cstddef>
#include <cstdlib>

#include "base/logging.h"
#include "pagespeed/kernel/base/function.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/string_writer.h"
#include "pagespeed/kernel/base/thread_annotations.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/sharedmem/shared_dynamic_string_map.h"
#include "pagespeed/kernel/util/platform.h"

namespace net_instaweb {

namespace {

const int kIntSize = sizeof(int); // NOLINT
// Should be a multiple of 4
const int kTableSize = 1024;
// +1 for string that causes overflow
const int kNumberOfStrings = kTableSize + 1;
const int kStringSize = 64;
const char kPrefix[] = "/prefix/";
const char kSuffix[] = "suffix";
const char kExampleString1[] = "http://www.example1.com";
const char kExampleString2[] = "http://www.example2.com";

}  // namespace

SharedDynamicStringMapTestBase::SharedDynamicStringMapTestBase(
    SharedMemTestEnv* test_env)
    : test_env_(test_env),
      shmem_runtime_(test_env->CreateSharedMemRuntime()),
      thread_system_(Platform::CreateThreadSystem()),
      handler_(thread_system_->NewMutex()) {
  // We must be able to fit a unique int in our string
  CHECK(2 * kIntSize < kStringSize - 1);
  // 255 because we can't use null char
  CHECK(kNumberOfStrings < pow(16, 2 * kIntSize));
  // After the int at the front we add random chars
  for (int i = 0; i < kNumberOfStrings; i++) {
    // We pad the beginning with the hex representation of i, a unique string
    // or non-null characters
    GoogleString string = StringPrintf("%0*x", 2 * kIntSize, i);
    // We fill the rest of the string with random lower-case letters
    // -1 so there's room for the terminating null character
    while (string.length() < kStringSize - 1) {
      string.push_back(random() % 26 + 'a');
    }
    strings_.push_back(string);
  }
}

bool SharedDynamicStringMapTestBase::CreateChild(TestMethod0 method) {
  Function* callback =
      new MemberFunction0<SharedDynamicStringMapTestBase>(method, this);
  return test_env_->CreateChild(callback);
}

bool SharedDynamicStringMapTestBase::CreateFillChild(TestMethod2 method,
                                                     int start,
                                                     int number_of_strings) {
  Function* callback =
      new MemberFunction2<SharedDynamicStringMapTestBase, int, int>(
          method, this, start, number_of_strings);
  return test_env_->CreateChild(callback);
}

SharedDynamicStringMap* SharedDynamicStringMapTestBase::ChildInit() {
  SharedDynamicStringMap* map =
      new SharedDynamicStringMap(kTableSize,
                                 kStringSize,
                                 shmem_runtime_.get(),
                                 kPrefix,
                                 kSuffix);
  map->InitSegment(false, &handler_);
  return map;
}

SharedDynamicStringMap* SharedDynamicStringMapTestBase::ParentInit() {
  SharedDynamicStringMap* map =
      new SharedDynamicStringMap(kTableSize,
                                 kStringSize,
                                 shmem_runtime_.get(),
                                 kPrefix,
                                 kSuffix);
  map->InitSegment(true, &handler_);
  return map;
}

void SharedDynamicStringMapTestBase::TestSimple() NO_THREAD_SAFETY_ANALYSIS {
  scoped_ptr<SharedDynamicStringMap> map(ParentInit());
  GoogleString output;
  StringWriter writer(&output);
  map->Dump(&writer, &handler_);
  EXPECT_EQ(output, "");
  EXPECT_EQ(0, map->GetNumberInserted());
  map->IncrementElement(kExampleString1);
  EXPECT_EQ(1, map->LookupElement(kExampleString1));
  output.clear();
  map->Dump(&writer, &handler_);
  EXPECT_EQ(output, "http://www.example1.com: 1\n");
  EXPECT_EQ(1, map->GetNumberInserted());
  map->GlobalCleanup(&handler_);
  EXPECT_EQ(0, handler_.SeriousMessages());
}

void SharedDynamicStringMapTestBase::TestCreate() {
  scoped_ptr<SharedDynamicStringMap> map(ParentInit());
  EXPECT_EQ(0, map->LookupElement(kExampleString1));
  EXPECT_EQ(0, map->LookupElement(kExampleString2));
  EXPECT_EQ(0, map->GetNumberInserted());
  map->IncrementElement(kExampleString1);
  map->IncrementElement(kExampleString2);
  EXPECT_EQ(1, map->LookupElement(kExampleString1));
  EXPECT_EQ(1, map->LookupElement(kExampleString2));
  EXPECT_EQ(2, map->GetNumberInserted());
  ASSERT_TRUE(CreateChild(&SharedDynamicStringMapTestBase::AddChild));
  test_env_->WaitForChildren();
  EXPECT_EQ(2, map->LookupElement(kExampleString1));
  EXPECT_EQ(2, map->LookupElement(kExampleString2));
  EXPECT_EQ(2, map->GetNumberInserted());
  map->GlobalCleanup(&handler_);
  EXPECT_EQ(0, handler_.SeriousMessages());
}

void SharedDynamicStringMapTestBase::AddChild() {
  scoped_ptr<SharedDynamicStringMap> map(ChildInit());
  if ((map->IncrementElement(kExampleString1) == 0) ||
      (map->IncrementElement(kExampleString2) == 0)) {
    test_env_->ChildFailed();
  }
}

void SharedDynamicStringMapTestBase::TestAdd() {
  scoped_ptr<SharedDynamicStringMap> map(ParentInit());
  for (int i = 0; i < 2; i++)
    ASSERT_TRUE(CreateChild(&SharedDynamicStringMapTestBase::AddChild));
  test_env_->WaitForChildren();
  EXPECT_EQ(2, map->LookupElement(kExampleString1));
  EXPECT_EQ(2, map->LookupElement(kExampleString2));
  EXPECT_EQ(2, map->GetNumberInserted());
  map->GlobalCleanup(&handler_);
  EXPECT_EQ(0, handler_.SeriousMessages());
}

void SharedDynamicStringMapTestBase::TestQuarterFull() {
  scoped_ptr<SharedDynamicStringMap> map(ParentInit());
  ASSERT_TRUE(CreateFillChild(&SharedDynamicStringMapTestBase::AddFillChild,
                              0,
                              kTableSize / 4));
  test_env_->WaitForChildren();
  EXPECT_EQ(kTableSize / 4, map->GetNumberInserted());
  GoogleString output;
  StringWriter writer(&output);
  map->Dump(&writer, &handler_);
  // Dump outputs the table data in the form
  // "<string1>: <value1>\n<string2>: <value2>\n<string3>: <value3>\n..."
  // In this case all values should be 1 so for each of the (kTableSize / 4)
  // strings there should be kStringSize characters plus a ":", " ", "1", and
  // "\n" and minus a null character; hence (kTablsize / 4) * (kStringSize + 3)
  EXPECT_EQ(static_cast<size_t>((kTableSize / 4) * (kStringSize + 3)),
            output.length());
  map->GlobalCleanup(&handler_);
  EXPECT_EQ(0, handler_.SeriousMessages());
}

void SharedDynamicStringMapTestBase::TestFillSingleThread() {
  scoped_ptr<SharedDynamicStringMap> map(ParentInit());
  EXPECT_EQ(0, map->GetNumberInserted());
  // One child fills the entire table.
  ASSERT_TRUE(CreateFillChild(&SharedDynamicStringMapTestBase::AddFillChild,
                              0,
                              kTableSize));
  test_env_->WaitForChildren();
  // Each entry should have been incremented once.
  for (int i = 0; i < kTableSize; i++)
    EXPECT_EQ(1, map->LookupElement(strings_[i]));
  EXPECT_EQ(kTableSize, map->GetNumberInserted());
  // One child increments the entire table.
  ASSERT_TRUE(CreateFillChild(&SharedDynamicStringMapTestBase::AddFillChild,
                              0,
                              kTableSize));
  test_env_->WaitForChildren();
  // Each entry should have been incremented twice.
  for (int i = 0; i < kTableSize; i++)
    EXPECT_EQ(2, map->LookupElement(strings_[i]));
  EXPECT_EQ(kTableSize, map->GetNumberInserted());
  // Once the table is full it should not accept additional strings.
  ASSERT_TRUE(CreateChild(&SharedDynamicStringMapTestBase::AddToFullTable));
  test_env_->WaitForChildren();
  EXPECT_EQ(kTableSize, map->GetNumberInserted());
  map->GlobalCleanup(&handler_);
  EXPECT_EQ(0, handler_.SeriousMessages());
}

void SharedDynamicStringMapTestBase::TestFillMultipleNonOverlappingThreads() {
  scoped_ptr<SharedDynamicStringMap> map(ParentInit());
  CHECK_EQ(kTableSize % 4, 0);
  // Each child will fill up 1/4 of the table.
  for (int i = 0; i < 4; i++)
    ASSERT_TRUE(CreateFillChild(&SharedDynamicStringMapTestBase::AddFillChild,
                                i * kTableSize / 4,
                                kTableSize / 4));
  test_env_->WaitForChildren();
  for (int i = 0; i < kTableSize; i++)
    EXPECT_EQ(1, map->LookupElement(strings_[i]));
  EXPECT_EQ(kTableSize, map->GetNumberInserted());
  // Once the table is full it should not accept additional strings.
  ASSERT_TRUE(CreateChild(&SharedDynamicStringMapTestBase::AddToFullTable));
  EXPECT_EQ(kTableSize, map->GetNumberInserted());
  test_env_->WaitForChildren();
  map->GlobalCleanup(&handler_);
  EXPECT_EQ(0, handler_.SeriousMessages());
}

void SharedDynamicStringMapTestBase::TestFillMultipleOverlappingThreads() {
  scoped_ptr<SharedDynamicStringMap> map(ParentInit());
  // Ensure that kTableSize is a multiple of 4.
  CHECK_EQ(kTableSize & 3, 0);
  // Each child will fill up 1/2 of the table - the table will get covered
  // twice.
  for (int i = 0; i < 4; i++)
    ASSERT_TRUE(CreateFillChild(&SharedDynamicStringMapTestBase::AddFillChild,
                                i * kTableSize / 4,
                                kTableSize / 2));
  // In addition, the parent is going to fill up the entire table.
  for (int i = 0; i < kTableSize; i++)
    ASSERT_NE(0, map->IncrementElement(strings_[i]));
  test_env_->WaitForChildren();
  EXPECT_EQ(kTableSize, map->GetNumberInserted());
  // Hence, we check that the values are equal to 3.
  for (int i = 0; i < kTableSize; i++)
    EXPECT_EQ(3, map->LookupElement(strings_[i]));
  // Once the table is full it should not accept additional strings.
  ASSERT_TRUE(CreateChild(&SharedDynamicStringMapTestBase::AddToFullTable));
  test_env_->WaitForChildren();
  EXPECT_EQ(kTableSize, map->GetNumberInserted());
  map->GlobalCleanup(&handler_);
  EXPECT_EQ(0, handler_.SeriousMessages());
}

void SharedDynamicStringMapTestBase::AddFillChild(int start,
                                                  int number_of_strings) {
  scoped_ptr<SharedDynamicStringMap> map(ChildInit());
  for (int i = 0; i < number_of_strings; i++) {
    if (0 == map->IncrementElement(strings_[(i + start) % kTableSize]))
      test_env_->ChildFailed();
  }
}

void SharedDynamicStringMapTestBase::AddToFullTable() {
  scoped_ptr<SharedDynamicStringMap> map(ChildInit());
  const char* string = strings_[kTableSize].c_str();
  EXPECT_EQ(0, map->IncrementElement(string));
}

}  // namespace net_instaweb
