172961230a5890071bcca436eb5630172ce84ec41Andreas Huber/*
272961230a5890071bcca436eb5630172ce84ec41Andreas Huber * Copyright (C) 2010 The Android Open Source Project
372961230a5890071bcca436eb5630172ce84ec41Andreas Huber *
472961230a5890071bcca436eb5630172ce84ec41Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
572961230a5890071bcca436eb5630172ce84ec41Andreas Huber * you may not use this file except in compliance with the License.
672961230a5890071bcca436eb5630172ce84ec41Andreas Huber * You may obtain a copy of the License at
772961230a5890071bcca436eb5630172ce84ec41Andreas Huber *
872961230a5890071bcca436eb5630172ce84ec41Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
972961230a5890071bcca436eb5630172ce84ec41Andreas Huber *
1072961230a5890071bcca436eb5630172ce84ec41Andreas Huber * Unless required by applicable law or agreed to in writing, software
1172961230a5890071bcca436eb5630172ce84ec41Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1272961230a5890071bcca436eb5630172ce84ec41Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1372961230a5890071bcca436eb5630172ce84ec41Andreas Huber * See the License for the specific language governing permissions and
1472961230a5890071bcca436eb5630172ce84ec41Andreas Huber * limitations under the License.
1572961230a5890071bcca436eb5630172ce84ec41Andreas Huber */
1672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
1772961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include <sys/types.h>
1872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
1972961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "AAtomizer.h"
2072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2172961230a5890071bcca436eb5630172ce84ec41Andreas Hubernamespace android {
2272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2372961230a5890071bcca436eb5630172ce84ec41Andreas Huber// static
2472961230a5890071bcca436eb5630172ce84ec41Andreas HuberAAtomizer AAtomizer::gAtomizer;
2572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2672961230a5890071bcca436eb5630172ce84ec41Andreas Huber// static
2772961230a5890071bcca436eb5630172ce84ec41Andreas Huberconst char *AAtomizer::Atomize(const char *name) {
2872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return gAtomizer.atomize(name);
2972961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
3072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
3172961230a5890071bcca436eb5630172ce84ec41Andreas HuberAAtomizer::AAtomizer() {
3272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    for (size_t i = 0; i < 128; ++i) {
3372961230a5890071bcca436eb5630172ce84ec41Andreas Huber        mAtoms.push(List<AString>());
3472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
3572961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
3672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
3772961230a5890071bcca436eb5630172ce84ec41Andreas Huberconst char *AAtomizer::atomize(const char *name) {
3872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Mutex::Autolock autoLock(mLock);
3972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
4072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    const size_t n = mAtoms.size();
4172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    size_t index = AAtomizer::Hash(name) % n;
4272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    List<AString> &entry = mAtoms.editItemAt(index);
4372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    List<AString>::iterator it = entry.begin();
4472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    while (it != entry.end()) {
4572961230a5890071bcca436eb5630172ce84ec41Andreas Huber        if ((*it) == name) {
4672961230a5890071bcca436eb5630172ce84ec41Andreas Huber            return (*it).c_str();
4772961230a5890071bcca436eb5630172ce84ec41Andreas Huber        }
4872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        ++it;
4972961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
5072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
5172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    entry.push_back(AString(name));
5272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
5372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return (*--entry.end()).c_str();
5472961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
5572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
5672961230a5890071bcca436eb5630172ce84ec41Andreas Huber// static
5772961230a5890071bcca436eb5630172ce84ec41Andreas Huberuint32_t AAtomizer::Hash(const char *s) {
5872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    uint32_t sum = 0;
5972961230a5890071bcca436eb5630172ce84ec41Andreas Huber    while (*s != '\0') {
6072961230a5890071bcca436eb5630172ce84ec41Andreas Huber        sum = (sum * 31) + *s;
6172961230a5890071bcca436eb5630172ce84ec41Andreas Huber        ++s;
6272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
6372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
6472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return sum;
6572961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
6672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
6772961230a5890071bcca436eb5630172ce84ec41Andreas Huber}  // namespace android
68