外文ubuntu社区论坛的精华贴选,长期翻译更新中……

参与到Ubuntu的翻译中来
回复
头像
tonychen123
帖子: 101
注册时间: 2009-04-03 20:52
来自: Guangzhou -China

外文ubuntu社区论坛的精华贴选,长期翻译更新中……

#1

帖子 tonychen123 » 2009-07-25 0:35

虽然我用ubuntu不到半年,但一用上,我就不可以再离开ubuntu了……
想为社区做点贡献,只是能力还有限,力不从心。我订阅了ubuntu官网英文论坛,查看到有用的贴,就拿来这与大家分享吧,并作力所能及的翻译,只作意译哦,大家一定要支持哦!
ubuntu forums:http://ubuntuforums.org/,让我们与世界同步,有兴趣的跟我一起来!

带头贴先跟大家分享一副图表,这副图从整体上解释了自由软件的概念(Free Software Concept Map),作者表示,他作这图采取的意见是:把零散的概念都集合到一个整体概念图里去将简化很多问题(Less concepts in one concept map makes it easier.)。官网链接是:http://bulma.net/body.phtml?nIdNoticia=2277
map-en-i-800.png
早期版本:
MapangKonseptualngLibrengSoftware.png
两幅图以GPL协议发布,原帖链接是:http://ubuntuforums.org/showthread.php?t=1221769
There should be one-- and preferably only one --obvious way to do it.
kentty
帖子: 219
注册时间: 2005-11-09 19:48

Re: 外文ubuntu社区论坛的精华贴选,长期翻译更新中……

#2

帖子 kentty » 2009-07-25 1:09

强烈支持! :em11 看你能坚持多久。 :em04
头像
tonychen123
帖子: 101
注册时间: 2009-04-03 20:52
来自: Guangzhou -China

Re: 外文ubuntu社区论坛的精华贴选,长期翻译更新中……

#3

帖子 tonychen123 » 2009-07-25 1:16

其实看了看,很多的那论坛上的东西,能有价值的,没有多少,就当转载下有价值的,有意思的,可能很久才更新,不过会坚持的 :em11
There should be one-- and preferably only one --obvious way to do it.
头像
tonychen123
帖子: 101
注册时间: 2009-04-03 20:52
来自: Guangzhou -China

Re: 外文ubuntu社区论坛的精华贴选,长期翻译更新中……

#4

帖子 tonychen123 » 2009-07-25 2:31

免翻译吧,偷懒……
nice hashmap for C
从 Ubuntu Forums 作者:manualqr
Every time I want to do a little bit of hobby programming, I consider what I want to get done and which language to do it in. It used to be that C almost never got picked because there was no way to use <feature foo>.

One of those features were hashmaps. C++ offers map and unordered_map from the STL, and there are many great libraries (e.g google's sparse-hash) that work well.

I found a couple C hashmap implementations online but most of them were limited in some way, or just not to my liking. So I wrote my own, and I want to share it..

Features:
* maps keys to values :). e.g char* to double, long to int, etc.
* can grow (i.e not limited to n values)
* uses simple bools to indicate errors
* insert and find functions
* option to make the hashmap thread safe
* option to use a destructor when deleting the hashmap
* option to build a hash functions (for integer keys)
* uses open-addressing to resolve collisions (and rehashes before the load degrades performance to the level of closed-addressing)
* (relatively) friendly interface: macros are used to handle casting for you

API:
* hashmap mk_hmap(hash function, equality function, optional destructor)
* bool hmap_add(hashmap, key, value)
* val hmap_get(hashmap, key)

I've done some basic tests with this and it seems to work well.. I don't have a reliable benchmark, so I won't post numbers.. But keep in mind, the hashmap implementation isn't normally a bottleneck - it's usually the hash function.

Code:

代码: 全选

/*
 * hashmap.h
 * Copyright (c) 2009 Vedant Kumar
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#pragma once

#define HMAP_PRESET_SIZE        2 << 6 // use a power of 2 for faster array access
#define HMAP_GROWTH_RATE        2
#define HMAP_MAKE_HASHFN
#define HMAP_THREAD_SAFE        // build with -lrt
#define HMAP_DESTRUCTORS

#ifdef HMAP_THREAD_SAFE
        #include <semaphore.h>
#endif

#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>

typedef void* key;
typedef void* val;

typedef struct key_val_map {
        key k;
        val v;
} key_val_map;

typedef struct hashmap {
        key_val_map *map;
        uint32_t size;
        uint32_t capacity;
        uint32_t (*hash_fn)(key);
        bool (*eq_fn)(key, key);
#ifdef HMAP_DESTRUCTORS
        void (*del_fn)(val);
#endif
#ifdef HMAP_THREAD_SAFE
        sem_t lock;
#endif
} hashmap;

// hashmaps need a hash function, an equality function, and a destructor
hashmap mk_hmap(uint32_t (*hash_fn)(key),
                                bool (*eq_fn)(key, key)
                        #ifdef HMAP_DESTRUCTORS
                                , void (*del_fn)(val)
                        #endif
                                ) {
                                       
        hashmap hmap;
        hmap.map = (key_val_map*) malloc(sizeof(key_val_map) * HMAP_PRESET_SIZE);
        hmap.size = 0;
        hmap.capacity = HMAP_PRESET_SIZE;
        hmap.hash_fn = hash_fn;
        hmap.eq_fn = eq_fn;
#ifdef HMAP_DESTRUCTORS
        hmap.del_fn = del_fn;
#endif
#ifdef HMAP_THREAD_SAFE
        sem_init(&hmap.lock, 0, 1);
#endif
        return hmap;
}

void free_hmap(hashmap* hmap) {
#ifdef HMAP_THREAD_SAFE
        sem_wait(&hmap->lock);
#endif

#ifdef HMAP_DESTRUCTORS
        static uint32_t it;
        for (it=0; it < hmap->size; ++it) {
                if (hmap->map[it].v != NULL) {
                        hmap->del_fn(hmap->map[it].v);
                }
        }
#endif

        free(hmap->map);
       
#ifdef HMAP_THREAD_SAFE
        sem_post(&hmap->lock);
#endif
}
 
void __oa_hmap_add(key_val_map* map, uint32_t size, uint32_t (*hash_fn)(key),
                                  key in, val out) {
        static uint32_t hash;
        hash = hash_fn(in) % size;
       
        while (map[hash].v != NULL) {
                hash = (hash + 1) % size;
        }
       
        map[hash].k = in;
        map[hash].v = out;
}

bool __hmap_add(hashmap* hmap, key in, val out) {
#ifdef HMAP_THREAD_SAFE
        sem_wait(&hmap->lock);
#endif

        // performace degrades after a certain load
        if (((float) hmap->size) / hmap->capacity > 0.70) {
                key_val_map* temp = (key_val_map*) malloc(hmap->capacity * HMAP_GROWTH_RATE);
                if (temp != NULL) {
                        hmap->capacity *= HMAP_GROWTH_RATE;
                } else {
                #ifdef HMAP_THREAD_SAFE
                        sem_post(&hmap->lock);
                #endif
                        // we're out of memory
                        return false;
                }
               
                // re-posn all elements
                static uint32_t it;
                for (it=0; it < hmap->capacity; ++it) {
                        if (hmap->map[it].v != NULL) {
                                __oa_hmap_add(temp, hmap->capacity, hmap->hash_fn, in, out);
                        }
                }
               
                // swap out the old map with the new one
                free(hmap->map);
                hmap->map = temp;
        }
       
        __oa_hmap_add(hmap->map, hmap->capacity, hmap->hash_fn, in, out);
        hmap->size += 1;

#ifdef HMAP_THREAD_SAFE
        sem_post(&hmap->lock);
#endif

        return true;
}

#define hmap_add(hmap, in, out) __hmap_add(&hmap, (key) in, (val) out)

val __hmap_get(hashmap* hmap, key in) {
#ifdef HMAP_THREAD_SAFE
        sem_wait(&hmap->lock);
#endif

        static uint32_t hash;
        hash = hmap->hash_fn(in) % hmap->capacity;
       
        while (hmap->map[hash].v != NULL) {
                if (hmap->eq_fn(in, hmap->map[hash].k)) {
                #ifdef HMAP_THREAD_SAFE
                        sem_post(&hmap->lock);
                #endif                       
                       
                        return hmap->map[hash].v;
                }
               
                hash = (hash + 1) % hmap->capacity;
        }

       
#ifdef HMAP_THREAD_SAFE
        sem_post(&hmap->lock);
#endif
       
        return NULL;
}

#define hmap_get(hmap, obj) __hmap_get(&hmap, (val) obj)       

#ifdef HMAP_MAKE_HASHFN
// Robert Jenkins' 32 bit integer hash function
uint32_t int_hash_fn(key in) {
        static uint32_t a;
        a = *((uint32_t*) in);
       
        a = (a+0x7ed55d16) + (a<<12);
        a = (a^0xc761c23c) ^ (a>>19);
        a = (a+0x165667b1) + (a<<5);
        a = (a+0xd3a2646c) ^ (a<<9);
        a = (a+0xfd7046c5) + (a<<3);
        a = (a^0xb55a4f09) ^ (a>>16);
       
        return a;
}

bool int_eq_fn(key a, key b) {
        return *((uint32_t*) a) == *((uint32_t*) b) ? true : false;
}

#endif
Enjoy!

(If anyone would like to implement hmap_del, go for it!)

原帖链接:http://ubuntuforums.org/showthread.php?t=1222055
There should be one-- and preferably only one --obvious way to do it.
头像
adagio
论坛版主
帖子: 22110
注册时间: 2008-02-17 23:47
来自: 美丽富饶的那啥星球

Re: 外文ubuntu社区论坛的精华贴选,长期翻译更新中……

#5

帖子 adagio » 2009-07-25 9:43

至少把图翻译一下吧 :em06
明天就换大三八!
——8核CPU、8G内存、8T硬盘……
8卡交火,80寸大屏放8个……
IPv8的光纤要8条……

---------------------------------------------------------------------------------
[图片版]新手当自强(续)FAQ
[新手进阶]挂载、fstab、调整linux分区
[图片版]E17桌面环境配置手把手
头像
hcym
帖子: 15634
注册时间: 2007-05-06 2:46

Re: 外文ubuntu社区论坛的精华贴选,长期翻译更新中……

#6

帖子 hcym » 2009-07-25 11:35

这哥们才4楼就化了

:em04
头像
Lavande
论坛版主
帖子: 5352
注册时间: 2008-12-21 15:27
来自: TARDIS

Re: 外文ubuntu社区论坛的精华贴选,长期翻译更新中……

#7

帖子 Lavande » 2009-07-25 11:50

:em20 整点小技巧什么的吧
这个一帖一堆代码,看不进去…… :em20
头像
highwind
帖子: 1362
注册时间: 2008-09-05 23:31
系统: LinuxMint17

Re: 外文ubuntu社区论坛的精华贴选,长期翻译更新中……

#8

帖子 highwind » 2009-07-25 17:34

纯支持 :em11
回复