12fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* 22fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * Copyright (C) 2013, The Android Open Source Project 32fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * 42fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * Licensed under the Apache License, Version 2.0 (the "License"); 52fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * you may not use this file except in compliance with the License. 62fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * You may obtain a copy of the License at 72fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * 82fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * http://www.apache.org/licenses/LICENSE-2.0 92fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * 102fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * Unless required by applicable law or agreed to in writing, software 112fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * distributed under the License is distributed on an "AS IS" BASIS, 122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * See the License for the specific language governing permissions and 142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * limitations under the License. 152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa */ 162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 1788bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/sparse_table.h" 182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasanamespace latinime { 202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaconst int SparseTable::NOT_EXIST = -1; 222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaconst int SparseTable::INDEX_SIZE = 4; 232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool SparseTable::contains(const int id) const { 252fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int readingPos = getPosInIndexTable(id); 262fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (id < 0 || mIndexTableBuffer->getTailPosition() <= readingPos) { 272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return false; 282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int index = mIndexTableBuffer->readUint(INDEX_SIZE, readingPos); 302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return index != NOT_EXIST; 312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasauint32_t SparseTable::get(const int id) const { 342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int indexTableReadingPos = getPosInIndexTable(id); 352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int index = mIndexTableBuffer->readUint(INDEX_SIZE, indexTableReadingPos); 362fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int contentTableReadingPos = getPosInContentTable(id, index); 37ef665816d07daa9aea74b4f8c34939b6801bbbcdKeisuke Kuroyanagi if (contentTableReadingPos < 0 38ef665816d07daa9aea74b4f8c34939b6801bbbcdKeisuke Kuroyanagi || contentTableReadingPos >= mContentTableBuffer->getTailPosition()) { 39ef665816d07daa9aea74b4f8c34939b6801bbbcdKeisuke Kuroyanagi AKLOGE("contentTableReadingPos(%d) is invalid. id: %d, index: %d", 40ef665816d07daa9aea74b4f8c34939b6801bbbcdKeisuke Kuroyanagi contentTableReadingPos, id, index); 41ef665816d07daa9aea74b4f8c34939b6801bbbcdKeisuke Kuroyanagi return NOT_A_DICT_POS; 42ef665816d07daa9aea74b4f8c34939b6801bbbcdKeisuke Kuroyanagi } 439b08a9e61168a5cc433f8491e797308118257506Keisuke Kuroyanagi const int contentValue = mContentTableBuffer->readUint(mDataSize, contentTableReadingPos); 449b08a9e61168a5cc433f8491e797308118257506Keisuke Kuroyanagi return contentValue == NOT_EXIST ? NOT_A_DICT_POS : contentValue; 452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool SparseTable::set(const int id, const uint32_t value) { 482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int posInIndexTable = getPosInIndexTable(id); 492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // Extends the index table if needed. 504c9377043060d1b68ac408fd99adc91be4c99484Keisuke Kuroyanagi int tailPos = mIndexTableBuffer->getTailPosition(); 514c9377043060d1b68ac408fd99adc91be4c99484Keisuke Kuroyanagi while (tailPos <= posInIndexTable) { 524c9377043060d1b68ac408fd99adc91be4c99484Keisuke Kuroyanagi if (!mIndexTableBuffer->writeUintAndAdvancePosition(NOT_EXIST, INDEX_SIZE, &tailPos)) { 534c9377043060d1b68ac408fd99adc91be4c99484Keisuke Kuroyanagi AKLOGE("cannot extend index table. tailPos: %d to: %d", tailPos, posInIndexTable); 544c9377043060d1b68ac408fd99adc91be4c99484Keisuke Kuroyanagi return false; 552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 562fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 572fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (contains(id)) { 582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // The entry is already in the content table. 592fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int index = mIndexTableBuffer->readUint(INDEX_SIZE, posInIndexTable); 602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (!mContentTableBuffer->writeUint(value, mDataSize, getPosInContentTable(id, index))) { 612fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("cannot update value %d. pos: %d, tailPos: %d, mDataSize: %d", value, 622fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa getPosInContentTable(id, index), mContentTableBuffer->getTailPosition(), 632fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa mDataSize); 642fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return false; 652fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return true; 672fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // The entry is not in the content table. 692fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // Create new entry in the content table. 702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int index = getIndexFromContentTablePos(mContentTableBuffer->getTailPosition()); 712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (!mIndexTableBuffer->writeUint(index, INDEX_SIZE, posInIndexTable)) { 722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("cannot write index %d. pos %d", index, posInIndexTable); 732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return false; 742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // Write a new block that containing the entry to be set. 762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa int writingPos = getPosInContentTable(0 /* id */, index); 772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa for (int i = 0; i < mBlockSize; ++i) { 789b08a9e61168a5cc433f8491e797308118257506Keisuke Kuroyanagi if (!mContentTableBuffer->writeUintAndAdvancePosition(NOT_EXIST, mDataSize, 792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa &writingPos)) { 802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("cannot write content table to extend. writingPos: %d, tailPos: %d, " 812fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa "mDataSize: %d", writingPos, mContentTableBuffer->getTailPosition(), mDataSize); 822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return false; 832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 852fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return mContentTableBuffer->writeUint(value, mDataSize, getPosInContentTable(id, index)); 862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 882fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaint SparseTable::getIndexFromContentTablePos(const int contentTablePos) const { 892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return contentTablePos / mDataSize / mBlockSize; 902fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaint SparseTable::getPosInIndexTable(const int id) const { 932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return (id / mBlockSize) * INDEX_SIZE; 942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaint SparseTable::getPosInContentTable(const int id, const int index) const { 972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int offset = id % mBlockSize; 982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return (index * mBlockSize + offset) * mDataSize; 992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 1002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 1012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} // namespace latinime 102