算法练习:有版本号的key-value store

要求

写一个kv store,需要实现按版本查找的method,简单的每次take新snapshot,就把map复制一次,放到list里面,这样按版本找可以实现O(1)。如果想省空间可以次snapshot只存diff。查的时候要把每个snapshot都查一次,就变成O(num_snapshots)。

Python 实现

class kvstore:
    def __init__(self):
        self.store = {}
        self.snapshots = []
        self.changed_keys = set()

    def set(self, k, v):
        self.store[k] = v
        self.changed_keys.add(k)

    def get(self, k):
        return self.store.get(k, None) 

    def snapshot(self):
        d = {}
        for k in self.changed_keys:
            d[k] = self.store[k]
        self.snapshots.append(d)
        self.changed_keys = set()
        return len(self.snapshots) - 1

    def get_from_snap(self, snap_version, key):
        for version in range(snap_version, -1, -1):
            if key in self.snapshots[version]:
                return self.snapshots[version][key]
        return None

store = kvstore()
store.set("k1",  "v1")
store.set("k2", "v2")

assert store.get("k1") == "v1"

last_snapshot = store.snapshot()
assert last_snapshot == 0
assert store.get("k1") == "v1"
assert store.get_from_snap(last_snapshot, "k1") == "v1"
assert store.get_from_snap(last_snapshot, "k2") == "v2"
assert store.get_from_snap(last_snapshot, "k3") == None

last_snapshot = store.snapshot()
assert last_snapshot == 1
assert store.get("k1") == "v1"
assert store.get_from_snap(last_snapshot, "k1") == "v1"
assert store.get_from_snap(last_snapshot, "k2") == "v2"
assert store.get_from_snap(last_snapshot, "k3") == None

store.set("k3", "v3")
store.set("k2", "k2-1")
last_snapshot = store.snapshot()
assert last_snapshot == 2
assert store.get("k1") == "v1"
assert store.get_from_snap(last_snapshot, "k1") == "v1"
assert store.get_from_snap(last_snapshot, "k2") == "k2-1"
assert store.get_from_snap(last_snapshot, "k3") == "v3"

MySQL 笔记

创建新用户 create a new user

mysql> create user 'someuser'@'localhost' identified by 'somepassword';

创建新数据库 create new database

mysql> create database some_db_name

赋予用户使用权利 Grant privileges to a user

mysql> GRANT ALL PRIVILEGES ON database_name.* TO 'some_user'@'localhost';

参考资料

MySQL功能非常齐全,每个命令都有很多细节,本文只收集一下基本用法,更多可以看这个网页和官方文档。

在Mac OS上安装Apache2, PHP, MySQL

最近想在Mac上装个wordpress,自然得先安装Apache2, PHP, MySQL。

简单科普一下这些软件

Apache:Web server, 处理http请求
PHP: 用来写网站逻辑的语言
MySQL: 数据库

WordPress就是一个用PHP写得程序,用PHP写的逻辑决定怎样处理http request,而数据就写在MySQL里面。

本来还想着用MAMP,这个是我很多年前用过的一个Mac软件,做个个界面打包管理以上软件。最近发现改成收费的了。于是Google一下直接在Mac OS上手动安装,毕竟Mac OS就是UNIX,不会太难。结果发现Mac OS基本都自带了。MAMP彻底没什么用了。

本文用的是Mac OS Catalina。

Apache2

启动Apahce2

% sudo apachectl start

浏览器打开http://localhost/,确认工作。

让Apache2可以使用PHP

cd /etc/apache2
cp httpd.conf httpd.conf.backup

编辑文件,

% sudo mvim httpd.conf

把下面这行的注释取消(删除开头的“#“)

LoadModule php7_module libexec/apache2/libphp7.so

重启Apache2

% sudo apachectl restart

找到Document Root。Document Root就是硬盘上存放html或者PHP文件的地方。

% grep DocumentRoot httpd.conf
# DocumentRoot: The directory out of which you will serve your
DocumentRoot "/Library/WebServer/Documents"
    # access content that does not live under the DocumentRoot.

可见Mac OS里document root在/Library/WebServer/Documents。

测试PHP正常工作

% cd /Library/WebServer/Documents
% sudo mvim phpinfo.php

phpinfo.php内容如下

<?php phpinfo();

然后打开网页http://localhost/phpinfo.php测试,能看到显示PHP信息就表示成功了。

Mac OS下安装MySQL

MySQL官网下载。我下的是这个

打开dmg文件以后运行里面的pkg文件安装。中间需要给root设置密码。

安装目录在

/usr/local/mysql

确定mysql server正在运行

ps aux | grep -i mysqld

方便起见,需要把mysql命令加到PATH里面。编辑.zprofile

% mvim ~/.zprofile

添加下面一行

PATH=/usr/local/mysql/bin:$PATH

新开一个terminal,测试用mysql client登陆

mysql -u root -p

输入安装时设置的root密码,登陆进去后尝试

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

能看到返回说明安装成功。

参考资料

本文参考了这篇英文博文。写得非常清楚,我添加了一些细节。作者Jason McCreary,他的网页里有很多很好的技术文章,值得收藏。