16b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi/*
26b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi * Copyright (C) 2014, The Android Open Source Project
36b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi *
46b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi * Licensed under the Apache License, Version 2.0 (the "License");
56b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi * you may not use this file except in compliance with the License.
66b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi * You may obtain a copy of the License at
76b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi *
86b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi *     http://www.apache.org/licenses/LICENSE-2.0
96b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi *
106b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi * Unless required by applicable law or agreed to in writing, software
116b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi * distributed under the License is distributed on an "AS IS" BASIS,
126b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi * See the License for the specific language governing permissions and
146b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi * limitations under the License.
156b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi */
166b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
176b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi#ifndef LATINIME_LANGUAGE_MODEL_DICT_CONTENT_GLOBAL_COUNTERS_H
186b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi#define LATINIME_LANGUAGE_MODEL_DICT_CONTENT_GLOBAL_COUNTERS_H
196b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
206b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi#include <cstdio>
216b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
226b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi#include "defines.h"
2388bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/buffer_with_extendable_buffer.h"
2488bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/dict_file_writing_utils.h"
256b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi#include "utils/byte_array_view.h"
266b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
276b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanaginamespace latinime {
286b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
296b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagiclass LanguageModelDictContentGlobalCounters {
306b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi public:
316b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    explicit LanguageModelDictContentGlobalCounters(const ReadWriteByteArrayView buffer)
326b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi            : mBuffer(buffer, 0 /* maxAdditionalBufferSize */),
336b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi              mTotalCount(readValue(mBuffer, TOTAL_COUNT_INDEX)),
346b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi              mMaxValueOfCounters(readValue(mBuffer, MAX_VALUE_OF_COUNTERS_INDEX)) {}
356b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
366b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    LanguageModelDictContentGlobalCounters()
376b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi            : mBuffer(0 /* maxAdditionalBufferSize */), mTotalCount(0), mMaxValueOfCounters(0) {}
386b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
396b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    bool needsToHalveCounters() const {
406b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        return mMaxValueOfCounters >= COUNTER_VALUE_NEAR_LIMIT_THRESHOLD
416b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi                || mTotalCount >= TOTAL_COUNT_VALUE_NEAR_LIMIT_THRESHOLD;
426b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    }
436b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
446b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    int getTotalCount() const {
456b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        return mTotalCount;
466b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    }
476b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
486b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    bool save(FILE *const file) const {
496b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        BufferWithExtendableBuffer bufferToWrite(
506b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi                BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE);
516b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        if (!bufferToWrite.writeUint(mTotalCount, COUNTER_SIZE_IN_BYTES,
526b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi                TOTAL_COUNT_INDEX * COUNTER_SIZE_IN_BYTES)) {
536b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi            return false;
546b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        }
556b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        if (!bufferToWrite.writeUint(mMaxValueOfCounters, COUNTER_SIZE_IN_BYTES,
566b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi                MAX_VALUE_OF_COUNTERS_INDEX * COUNTER_SIZE_IN_BYTES)) {
576b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi            return false;
586b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        }
596b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        return DictFileWritingUtils::writeBufferToFileTail(file, &bufferToWrite);
606b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    }
616b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
626b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    void incrementTotalCount() {
636b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        mTotalCount += 1;
646b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    }
656b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
66bcb52d73e206cee86a2ea126a5c3f948103057c6Keisuke Kuroyanagi    void addToTotalCount(const int count) {
67bcb52d73e206cee86a2ea126a5c3f948103057c6Keisuke Kuroyanagi        mTotalCount += count;
68bcb52d73e206cee86a2ea126a5c3f948103057c6Keisuke Kuroyanagi    }
69bcb52d73e206cee86a2ea126a5c3f948103057c6Keisuke Kuroyanagi
706b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    void updateMaxValueOfCounters(const int count) {
716b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        mMaxValueOfCounters = std::max(count, mMaxValueOfCounters);
726b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    }
736b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
746b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    void halveCounters() {
756b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        mMaxValueOfCounters /= 2;
766b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        mTotalCount /= 2;
776b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    }
786b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
796b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagiprivate:
806b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    DISALLOW_COPY_AND_ASSIGN(LanguageModelDictContentGlobalCounters);
816b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
826b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    const static int COUNTER_VALUE_NEAR_LIMIT_THRESHOLD;
836b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    const static int TOTAL_COUNT_VALUE_NEAR_LIMIT_THRESHOLD;
846b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    const static int COUNTER_SIZE_IN_BYTES;
856b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    const static int TOTAL_COUNT_INDEX;
866b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    const static int MAX_VALUE_OF_COUNTERS_INDEX;
876b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
886b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    BufferWithExtendableBuffer mBuffer;
896b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    int mTotalCount;
906b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    int mMaxValueOfCounters;
916b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi
926b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    static int readValue(const BufferWithExtendableBuffer &buffer, const int index) {
936b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        const int pos = COUNTER_SIZE_IN_BYTES * index;
946b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        if (pos + COUNTER_SIZE_IN_BYTES > buffer.getTailPosition()) {
956b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi            return 0;
966b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        }
976b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi        return buffer.readUint(COUNTER_SIZE_IN_BYTES, pos);
986b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi    }
996b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi};
1006b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi} // namespace latinime
1016b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi#endif /* LATINIME_LANGUAGE_MODEL_DICT_CONTENT_GLOBAL_COUNTERS_H */
102