// 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.


#ifndef IMPALA_RUNTIME_STRING_BUFFER_H
#define IMPALA_RUNTIME_STRING_BUFFER_H

#include "common/status.h"
#include "runtime/mem-pool.h"
#include "runtime/mem-tracker.h"
#include "runtime/string-value.h"
#include "util/ubsan.h"

namespace impala {

/// Dynamic-sizable string (similar to std::string) but without as many
/// copies and allocations.
/// StringBuffer is a buffer of char allocated from 'pool'. Current usage and size of the
/// buffer are tracked in 'len_' and 'buffer_size_' respectively. It supports a subset of
/// the std::string functionality but will only allocate bigger string buffers as
/// necessary. std::string tries to be immutable and will reallocate very often.
/// std::string should be avoided in all hot paths.
class StringBuffer {
 public:
  /// C'tor for StringBuffer.  Memory backing the string will be allocated from
  /// the pool as necessary. Can optionally be initialized from a StringValue.
  StringBuffer(MemPool* pool, StringValue* str = NULL)
      : pool_(pool), buffer_(NULL), len_(0), buffer_size_(0) {
    DCHECK(pool_ != NULL);
    if (str != NULL) {
      buffer_ = str->ptr;
      len_ = buffer_size_ = str->len;
    }
  }

  /// Append 'str' to the current string, allocating a new buffer as necessary.
  /// Return error status if memory limit is exceeded.
  Status Append(const char* str, int64_t str_len) WARN_UNUSED_RESULT {
    int64_t new_len = len_ + str_len;
    if (UNLIKELY(new_len > buffer_size_)) RETURN_IF_ERROR(GrowBuffer(new_len));
    Ubsan::MemCpy(buffer_ + len_, str, str_len);
    len_ += str_len;
    return Status::OK();
  }

  /// Wrapper around append() for input type 'uint8_t'.
  Status Append(const uint8_t* str, int64_t str_len) WARN_UNUSED_RESULT {
    return Append(reinterpret_cast<const char*>(str), str_len);
  }

  /// Clear the underlying StringValue. The allocated buffer can be reused.
  void Clear() { len_ = 0; }

  /// Reset the usage and size of the buffer. Note that the allocated buffer is
  /// retained but cannot be reused.
  void Reset() {
    len_ = 0;
    buffer_size_ = 0;
    buffer_ = NULL;
  }

  /// Returns true if no byte is consumed in the buffer.
  bool IsEmpty() const { return len_ == 0; }

  /// Grows the buffer to be at least 'new_size', copying over the previous data
  /// into the new buffer. The old buffer is not freed. Return an error status if
  /// growing the buffer will exceed memory limit.
  Status GrowBuffer(int64_t new_size) WARN_UNUSED_RESULT {
    if (LIKELY(new_size > buffer_size_)) {
      int64_t old_size = buffer_size_;
      buffer_size_ = std::max<int64_t>(buffer_size_ * 2, new_size);
      char* new_buffer = reinterpret_cast<char*>(pool_->TryAllocate(buffer_size_));
      if (UNLIKELY(new_buffer == NULL)) {
        string details =
            strings::Substitute("StringBuffer failed to grow buffer from $0 to $1 bytes.",
                old_size, buffer_size_);
        return pool_->mem_tracker()->MemLimitExceeded(NULL, details, buffer_size_);
      }
      if (LIKELY(len_ > 0)) memcpy(new_buffer, buffer_, len_);
      buffer_ = new_buffer;
    }
    return Status::OK();
  }

  /// Returns the number of bytes consumed in the buffer.
  int64_t len() const { return len_; }

  /// Returns the pointer to the buffer. Note that it's the caller's responsibility
  /// to not retain the pointer to 'buffer_' across call to Append() as the buffer_
  /// may be relocated in Append().
  char* buffer() const { return buffer_; }

  /// Returns the size of the buffer.
  int64_t buffer_size() const { return buffer_size_; }

 private:
  MemPool* pool_;
  char* buffer_;
  int64_t len_;         // number of bytes consumed in the buffer.
  int64_t buffer_size_; // size of the buffer.
};

}

#endif
