[Lab] CMU 15-445/645 : Project#0 - C++ Primer

[Lab] CMU 15-445/645 : Project#0 - C++ Primer

背景

  • 这两年工作内容主要是数据库中间件开发,半路出家,缺少数据库内核的领域知识。仅靠使用经验很难再有提升了,计划从基础开始系统补充数据库领域知识。第一个目标是做完 CMU 15-445/645 的 lab,宁可慢慢做,但是保证一定独立完成。
  • fall2024 project列表
  • 第一个project是主要是熟悉c++开发,把开发环境准备好

环境准备

bustub 需要在ubuntu环境编译运行,我手上有个centos的服务器,因此准备采用ubuntu的docker,把常用依赖打成镜像,挂载一个本地目录。代码开发在centos,编译、运行、Debug在docker环境。过程熟悉一下相关工具和c++语法。

Docker 常用命令

命令 说明
docker run -t -i ubuntu:latest /bin/bash 运行镜像
docker ps 查看运行的容器
docker ps -a 查看所有容器,包括停止的
docker commit bbe7f183f00b bustub-sys 将container_id对应的容器的当前环境打一个镜像
docker images 查看本地可用的镜像
docker run -v path/cmu15445:/work -it bustub-sys /bin/bash -v挂载本地目录到容器内的指定目录
docker start 5aafed5504f9 启动container_id对应容器
docker exec -it 5aafed5504f9 /bin/bash 进入一个正在运行的容器

llvm 安装

bustub 环境依赖 clang 相关包。
安装 clang 相关包时遇到 "Unable to locate package" 错误。
clang 通常属于 LLVM 项目,特定版本的 clang 可能需要从 LLVM 官方仓库安装。

apt-get update
apt install -y wget software-properties-common
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
./llvm.sh 14

安装完成后,重新执行完成环境准备。

build_support/packages.sh

开发环境

  • 调试使用gdb和打印日志

  • 代码开发基于vim

    • 自动补全插件使用 coc.nvim
      image
      image

    • 代码格式化插件 vim-clang-format

    • 文件搜索插件 ctrlp.vim
      image

  • 使用 coc 时,发现项目内的头文件没有被识别出来,这里采用最直接的方式,将指定的头文件目录加到bashrc中,即当前目录所有已include结尾的路径

export CPATH=$(find /<path>/cmu15445/bustub-wys -type d -name include | tr '\n' ':')
export CPLUS_INCLUDE_PATH=$(find /<path>/cmu15445/bustub-wys -type d -name include | tr '\n' ':')

当前 vim 配置,后面继续优化

let mapleader = " "

autocmd vimenter * colorscheme gruvbox
"autocmd vimenter * NERDTree
call plug#begin('~/.vim/plugged')
Plug 'morhetz/gruvbox'
Plug 'preservim/nerdtree'
Plug 'ctrlpvim/ctrlp.vim'
" Use release branch (recommend)
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'rhysd/vim-clang-format'
call plug#end()

set list
set bg=dark
color desert
set nu
set nocompatible
set tabstop=2
set softtabstop=2
set shiftwidth=2
set expandtab
set cursorline
set autoindent
set backspace=2
set ff=unix
syntax on
vnoremap kj <ESC>
inoremap kj <ESC>
set foldmethod=indent
set ignorecase
set visualbell

set list

nnoremap <Space>rc :e ~/.vim/vimrc<CR>

"nnoremap <F2> :set invpaste paste?<CR>
"imap <F2> <C-O>:set invpaste paste?<CR>
"set pastetoggle=<F2>

" 设置NerdTree 
map <F3> :NERDTreeMirror<CR>
map <F3> :NERDTreeToggle<CR>

" use <tab> for trigger completion and navigate to the next complete item
function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~ '\s'
endfunction

inoremap <silent><expr> <Tab>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<Tab>" :
      \ coc#refresh()


" 跳转到定义
nmap <silent> gd <Plug>(coc-definition)
" 跳转到声明
nmap <silent> gD <Plug>(coc-declaration)
" 跳转到类型定义
nmap <silent> gy <Plug>(coc-type-definition)
" 跳转到实现
nmap <silent> gi <Plug>(coc-implementation)
" 跳转到引用
nmap <silent> gr <Plug>(coc-references)

"let g:clang_format#auto_format_on_insert_leave=1	"退出插入模式时自动格式化
"
"let g:clang_format#style_options = {
"            \ "AccessModifierOffset" : -4,
"            \ "AllowShortIfStatementsOnASingleLine" : "true",
"            \ "AlwaysBreakTemplateDeclarations" : "true",
"            \ "Standard" : "C++11"}
"
"" map to <Leader>cf in C++ code
"autocmd FileType c,cpp,objc nnoremap <buffer><Leader>cf :<C-u>ClangFormat<CR>
"autocmd FileType c,cpp,objc vnoremap <buffer><Leader>cf :ClangFormat<CR>
"" if you install vim-operator-user
"autocmd FileType c,cpp,objc map <buffer><Leader>x <Plug>(operator-clang-format)
"" Toggle auto formatting:
"" nmap <Leader>C :ClangFormatAutoToggle<CR>

" Use <Tab> and <S-Tab> to navigate the completion list
inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"

" Make <CR> auto-select the first completion item and notify coc.nvim to
" format on enter, <cr> could be remapped by other vim plugin
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
                              \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
  • 题目打包提交时,发现代码路径不是需要提交的文件,需要调整一下 build.make

Hyperloglog 理解

  1. Task1 实现的hyperloglog,实际上在通过前k位分桶,然后每个桶维护最大的左边开始连续的0的数量R[i],最后套公式计算期望的uniqie value数量
  2. Task2 实现的hyperloglog_prestore,是针对hyperloglog存储上有优化的版本。同样通过前k位分桶,但是每个桶维护最大的右边连续的0的数量R[i]。但是维护这个数量时,不是直接存储这个数字,而是将他的低4位bitset存在预先分配好内存的dense_bucket里,当他的超过4位时,将超出的位放到一个hash_map里,key是bucket_id,val是溢出的位的biset。最后,计算方法和hyperloglog一致

通过记录

image

小结

project0的卡点除了环境配置外,就是题目意思的理解不清楚,看了题目推荐的文章之后,想了一段时间才想明白它的意思。c++很多高级用法不熟悉,有的已经忘了,需要补习下。

posted @ 2025-07-26 00:05  RRRR_wys  阅读(35)  评论(0)    收藏  举报