/***************************************************************************** Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved. 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; version 2 of the License. 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ /******************************************************************//** @file include/fts0vlc.ic Full text variable length integer encoding/decoding. Created 2007-03-27 Sunny Bains *******************************************************/ #ifndef INNOBASE_FTS0VLC_IC #define INNOBASE_FTS0VLC_IC #include "fts0types.h" /******************************************************************//** Return length of val if it were encoded using our VLC scheme. FIXME: We will need to be able encode 8 bytes value @return length of value encoded, in bytes */ UNIV_INLINE ulint fts_get_encoded_len( /*================*/ ulint val) /* in: value to encode */ { if (val <= 127) { return(1); } else if (val <= 16383) { return(2); } else if (val <= 2097151) { return(3); } else if (val <= 268435455) { return(4); } else { /* Possibly we should care that on 64-bit machines ulint can contain values that we can't encode in 5 bytes, but fts_encode_int doesn't handle them either so it doesn't much matter. */ return(5); } } /******************************************************************//** Encode an integer using our VLC scheme and return the length in bytes. @return length of value encoded, in bytes */ UNIV_INLINE ulint fts_encode_int( /*===========*/ ulint val, /* in: value to encode */ byte* buf) /* in: buffer, must have enough space */ { ulint len; if (val <= 127) { *buf = (byte) val; len = 1; } else if (val <= 16383) { *buf++ = (byte)(val >> 7); *buf = (byte)(val & 0x7F); len = 2; } else if (val <= 2097151) { *buf++ = (byte)(val >> 14); *buf++ = (byte)((val >> 7) & 0x7F); *buf = (byte)(val & 0x7F); len = 3; } else if (val <= 268435455) { *buf++ = (byte)(val >> 21); *buf++ = (byte)((val >> 14) & 0x7F); *buf++ = (byte)((val >> 7) & 0x7F); *buf = (byte)(val & 0x7F); len = 4; } else { /* Best to keep the limitations of the 32/64 bit versions identical, at least for the time being. */ ut_ad(val <= 4294967295u); *buf++ = (byte)(val >> 28); *buf++ = (byte)((val >> 21) & 0x7F); *buf++ = (byte)((val >> 14) & 0x7F); *buf++ = (byte)((val >> 7) & 0x7F); *buf = (byte)(val & 0x7F); len = 5; } /* High-bit on means "last byte in the encoded integer". */ *buf |= 0x80; return(len); } /******************************************************************//** Decode and return the integer that was encoded using our VLC scheme. @return value decoded */ UNIV_INLINE ulint fts_decode_vlc( /*===========*/ byte** ptr) /* in: ptr to decode from, this ptr is incremented by the number of bytes decoded */ { ulint val = 0; for (;;) { byte b = **ptr; ++*ptr; val |= (b & 0x7F); /* High-bit on means "last byte in the encoded integer". */ if (b & 0x80) { break; } else { val <<= 7; } } return(val); } #endif