File storage_common.c¶
File List > cubrid > src > storage > storage_common.c
Go to the documentation of this file
/*
* Copyright 2008 Search Solution Corporation
* Copyright 2016 CUBRID Corporation
*
* 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.
*
*/
/*
* storage_common.c - Definitions and data types of disk related stuffs
* such as pages, file structures, and so on.
*/
#ident "$Id$"
#include <stdlib.h>
#include <assert.h>
#include "config.h"
#include "storage_common.h"
#include "memory_alloc.h"
#include "error_manager.h"
#include "system_parameter.h"
#include "environment_variable.h"
#include "file_io.h"
#include "tz_support.h"
#include "db_date.h"
#include "dbtype.h"
// XXX: SHOULD BE THE LAST INCLUDE HEADER
#include "memory_wrapper.hpp"
/* RESERVED_SIZE_IN_PAGE should be aligned */
#define RESERVED_SIZE_IN_PAGE (sizeof (FILEIO_PAGE_RESERVED) + sizeof (FILEIO_PAGE_WATERMARK))
PGLENGTH db_Io_page_size = IO_DEFAULT_PAGE_SIZE;
PGLENGTH db_Log_page_size = IO_DEFAULT_PAGE_SIZE;
PGLENGTH db_User_page_size = IO_DEFAULT_PAGE_SIZE - RESERVED_SIZE_IN_PAGE;
static PGLENGTH find_valid_page_size (PGLENGTH page_size);
/*
* db_set_page_size(): set the page size of system.
*
* returns: NO_ERROR if page size is set by given size, otherwise ER_FAILED
* io_page_size(IN): the IO page size
* log_page_size(IN): the LOG page size
*
* Note: Set the database page size to the given size. The given size
* must be power of 2, greater than or equal to 1K, and smaller
* than or equal to 16K.
*/
int
db_set_page_size (PGLENGTH io_page_size, PGLENGTH log_page_size)
{
assert (io_page_size >= IO_MIN_PAGE_SIZE && log_page_size >= IO_MIN_PAGE_SIZE);
if (io_page_size < IO_MIN_PAGE_SIZE || log_page_size < IO_MIN_PAGE_SIZE)
{
return ER_FAILED;
}
db_Io_page_size = find_valid_page_size (io_page_size);
db_User_page_size = db_Io_page_size - RESERVED_SIZE_IN_PAGE;
db_Log_page_size = find_valid_page_size (log_page_size);
if (db_Io_page_size != io_page_size || db_Log_page_size != log_page_size)
{
return ER_FAILED;
}
return NO_ERROR;
}
/*
* db_network_page_size(): find the network pagesize
*
* returns: network pagesize
*
* Note: Find the best network pagesize for C/S communications for
* given transaction/client.
*/
PGLENGTH
db_network_page_size (void)
{
return db_Io_page_size;
}
/*
* find_valid_page_size(): find the valid page size of system
*
* returns: page_size
* page_size(IN): the page size
*
* Note: Find the database pagesize with the given size, where the given size
* must be power of 2, greater than or equal to 1K, and smaller than or
* equal to 16K.
*/
static PGLENGTH
find_valid_page_size (PGLENGTH page_size)
{
PGLENGTH power2_page_size = page_size;
if (power2_page_size < IO_MIN_PAGE_SIZE)
{
power2_page_size = IO_MIN_PAGE_SIZE;
}
else if (power2_page_size > IO_MAX_PAGE_SIZE)
{
power2_page_size = IO_MAX_PAGE_SIZE;
}
else
{
if (!IS_POWER_OF_2 (power2_page_size))
{
/*
* Not a power of 2 or page size is too small
*
* Round the number to a power of two. Find smaller number that it is
* a power of two, and then shift to get larger number.
*/
while (!IS_POWER_OF_2 (power2_page_size))
{
if (power2_page_size < IO_MIN_PAGE_SIZE)
{
power2_page_size = IO_MIN_PAGE_SIZE;
break;
}
else
{
/* Turn off some bits but the left most one */
power2_page_size = power2_page_size & (power2_page_size - 1);
}
}
power2_page_size <<= 1;
if (power2_page_size < IO_MIN_PAGE_SIZE)
{
power2_page_size = IO_MIN_PAGE_SIZE;
}
else if (power2_page_size > IO_MAX_PAGE_SIZE)
{
power2_page_size = IO_MAX_PAGE_SIZE;
}
er_set (ER_WARNING_SEVERITY, ARG_FILE_LINE, ER_DTSR_BAD_PAGESIZE, 2, page_size, power2_page_size);
}
}
return power2_page_size;
}
void
db_print_data (DB_TYPE type, DB_DATA * data, FILE * fd)
{
int hour, minute, second, millisecond, month, day, year;
switch (type)
{
case DB_TYPE_SHORT:
fprintf (fd, "%d", data->sh);
break;
case DB_TYPE_INTEGER:
fprintf (fd, "%d", data->i);
break;
case DB_TYPE_BIGINT:
fprintf (fd, "%lld", (long long) data->bigint);
break;
case DB_TYPE_FLOAT:
fprintf (fd, "%f", data->f);
break;
case DB_TYPE_DOUBLE:
fprintf (fd, "%f", data->d);
break;
case DB_TYPE_DATE:
db_date_decode (&data->date, &month, &day, &year);
fprintf (fd, "%d / %d / %d", month, day, year);
break;
case DB_TYPE_TIME:
db_time_decode (&data->time, &hour, &minute, &second);
fprintf (fd, "%d:%d:%d", hour, minute, second);
break;
case DB_TYPE_TIMESTAMP:
case DB_TYPE_TIMESTAMPLTZ:
fprintf (fd, "%d", data->utime);
break;
case DB_TYPE_TIMESTAMPTZ:
fprintf (fd, "%d Z:%X", data->timestamptz.timestamp, data->timestamptz.tz_id);
break;
case DB_TYPE_DATETIME:
case DB_TYPE_DATETIMELTZ:
db_datetime_decode (&data->datetime, &month, &day, &year, &hour, &minute, &second, &millisecond);
fprintf (fd, "%d/%d/%d %d:%d:%d.%d", month, day, year, hour, minute, second, millisecond);
break;
case DB_TYPE_DATETIMETZ:
db_datetime_decode (&(data->datetimetz.datetime), &month, &day, &year, &hour, &minute, &second, &millisecond);
fprintf (fd, "%d/%d/%d %d:%d:%d.%d Z:%X", month, day, year, hour, minute, second, millisecond,
data->datetimetz.tz_id);
break;
case DB_TYPE_MONETARY:
fprintf (fd, "%f", data->money.amount);
switch (data->money.type)
{
case DB_CURRENCY_DOLLAR:
fprintf (fd, " dollars");
break;
case DB_CURRENCY_YEN:
fprintf (fd, " yens");
break;
case DB_CURRENCY_WON:
fprintf (fd, " wons");
break;
case DB_CURRENCY_TL:
fprintf (fd, " turkish lira");
break;
case DB_CURRENCY_BRITISH_POUND:
fprintf (fd, " pounds");
break;
case DB_CURRENCY_CAMBODIAN_RIEL:
fprintf (fd, " riels");
break;
case DB_CURRENCY_CHINESE_RENMINBI:
fprintf (fd, " renminbi");
break;
case DB_CURRENCY_INDIAN_RUPEE:
fprintf (fd, " rupees");
break;
case DB_CURRENCY_RUSSIAN_RUBLE:
fprintf (fd, " rubles");
break;
case DB_CURRENCY_AUSTRALIAN_DOLLAR:
fprintf (fd, " Australian dollars");
break;
case DB_CURRENCY_CANADIAN_DOLLAR:
fprintf (fd, " Canadian dollars");
break;
case DB_CURRENCY_BRASILIAN_REAL:
fprintf (fd, " reals");
break;
case DB_CURRENCY_ROMANIAN_LEU:
fprintf (fd, " lei");
break;
case DB_CURRENCY_EURO:
fprintf (fd, " euros");
break;
case DB_CURRENCY_SWISS_FRANC:
fprintf (fd, " Swiss francs");
break;
case DB_CURRENCY_DANISH_KRONE:
fprintf (fd, " Danish crowns");
break;
case DB_CURRENCY_NORWEGIAN_KRONE:
fprintf (fd, " Norwegian crowns");
break;
case DB_CURRENCY_BULGARIAN_LEV:
fprintf (fd, " levs");
break;
case DB_CURRENCY_VIETNAMESE_DONG:
fprintf (fd, " Vietnamese dongs");
break;
case DB_CURRENCY_CZECH_KORUNA:
fprintf (fd, " Czech crowns");
break;
case DB_CURRENCY_POLISH_ZLOTY:
fprintf (fd, " zloty");
break;
case DB_CURRENCY_SWEDISH_KRONA:
fprintf (fd, " Swedish crowns");
break;
case DB_CURRENCY_CROATIAN_KUNA:
fprintf (fd, " kunas");
break;
case DB_CURRENCY_SERBIAN_DINAR:
fprintf (fd, " dinars");
break;
default:
break;
}
break;
default:
fprintf (fd, "Undefined");
break;
}
}
int
recdes_allocate_data_area (RECDES * rec, int size)
{
char *data;
data = (char *) db_private_alloc (NULL, size);
if (data == NULL)
{
return ER_FAILED;
}
rec->data = data;
rec->area_size = size;
return NO_ERROR;
}
void
recdes_free_data_area (RECDES * rec)
{
db_private_free_and_init (NULL, rec->data);
}
void
recdes_set_data_area (RECDES * rec, char *data, int size)
{
rec->data = data;
rec->area_size = size;
}
char *
oid_to_string (char *buf, int buf_size, OID * oid)
{
snprintf (buf, buf_size, "(%d|%d|%d)", oid->volid, oid->pageid, oid->slotid);
buf[buf_size - 1] = 0;
return buf;
}
char *
vpid_to_string (char *buf, int buf_size, VPID * vpid)
{
snprintf (buf, buf_size, "(%d|%d)", vpid->volid, vpid->pageid);
buf[buf_size - 1] = 0;
return buf;
}
char *
vfid_to_string (char *buf, int buf_size, VFID * vfid)
{
snprintf (buf, buf_size, "(%d|%d)", vfid->volid, vfid->fileid);
buf[buf_size - 1] = 0;
return buf;
}
char *
hfid_to_string (char *buf, int buf_size, HFID * hfid)
{
snprintf (buf, buf_size, "(%d|%d|%d)", hfid->vfid.volid, hfid->vfid.fileid, hfid->hpgid);
buf[buf_size - 1] = 0;
return buf;
}
char *
btid_to_string (char *buf, int buf_size, BTID * btid)
{
snprintf (buf, buf_size, "(%d|%d|%d)", btid->vfid.volid, btid->vfid.fileid, btid->root_pageid);
buf[buf_size - 1] = 0;
return buf;
}