allocate returns a contiguous block of memory starting at a given page.
(txid common.Txid, count int)
| 1163 | |
| 1164 | // allocate returns a contiguous block of memory starting at a given page. |
| 1165 | func (db *DB) allocate(txid common.Txid, count int) (*common.Page, error) { |
| 1166 | // Allocate a temporary buffer for the page. |
| 1167 | var buf []byte |
| 1168 | if count == 1 { |
| 1169 | buf = db.pagePool.Get().([]byte) |
| 1170 | } else { |
| 1171 | buf = make([]byte, count*db.pageSize) |
| 1172 | } |
| 1173 | p := (*common.Page)(unsafe.Pointer(&buf[0])) |
| 1174 | p.SetOverflow(uint32(count - 1)) |
| 1175 | |
| 1176 | // Use pages from the freelist if they are available. |
| 1177 | p.SetId(db.freelist.Allocate(txid, count)) |
| 1178 | if p.Id() != 0 { |
| 1179 | return p, nil |
| 1180 | } |
| 1181 | |
| 1182 | // Resize mmap() if we're at the end. |
| 1183 | p.SetId(db.rwtx.meta.Pgid()) |
| 1184 | var minsz = int((p.Id()+common.Pgid(count))+1) * db.pageSize |
| 1185 | if db.MaxSize > 0 { |
| 1186 | nextAllocSize := minsz |
| 1187 | nextMmapSize, err := db.mmapSize(minsz) |
| 1188 | if err != nil { |
| 1189 | return nil, fmt.Errorf("mmap size calculation error: %w", err) |
| 1190 | } |
| 1191 | if runtime.GOOS == "windows" { |
| 1192 | // nextAllocSize may not exactly match nextMmapSize. |
| 1193 | // On Windows, this mismatch may cause the file size to slightly exceed maxSize, |
| 1194 | // while it is harmless on other platforms. |
| 1195 | nextAllocSize = nextMmapSize |
| 1196 | } else { |
| 1197 | // On non-Windows platforms, the database file is only grown explicitly in grow calls. |
| 1198 | nextAllocSize = db.growSize(nextMmapSize, nextAllocSize) |
| 1199 | } |
| 1200 | if nextAllocSize > db.MaxSize { |
| 1201 | db.Logger().Errorf("[GOOS: %s, GOARCH: %s] maximum db size reached, minSize: %d (allocSize: %d), db.MaxSize: %d", runtime.GOOS, runtime.GOARCH, minsz, nextAllocSize, db.MaxSize) |
| 1202 | return nil, berrors.ErrMaxSizeReached |
| 1203 | } |
| 1204 | } |
| 1205 | if minsz >= db.datasz { |
| 1206 | if err := db.mmap(minsz); err != nil { |
| 1207 | if err == berrors.ErrMaxSizeReached { |
| 1208 | return nil, err |
| 1209 | } else { |
| 1210 | return nil, fmt.Errorf("mmap allocate error: %s", err) |
| 1211 | } |
| 1212 | } |
| 1213 | } |
| 1214 | |
| 1215 | // Move the page id high water mark. |
| 1216 | curPgid := db.rwtx.meta.Pgid() |
| 1217 | db.rwtx.meta.SetPgid(curPgid + common.Pgid(count)) |
| 1218 | |
| 1219 | return p, nil |
| 1220 | } |
| 1221 | |
| 1222 | // grow grows the size of the database to the given sz. |
nothing calls this directly
no test coverage detected