Skip to content

Commit 03da759

Browse files
committed
ref: replace raw pointers in thor database with static references
needs to use cells in GameType struct, because this struct is mutated during search (which doesn't sem good)
1 parent 5cb241a commit 03da759

File tree

2 files changed

+64
-66
lines changed

2 files changed

+64
-66
lines changed

crates/legacy-zebra/src/thordb.rs

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use std::io::{Read, Write};
1818
use engine::src::game::to_lower;
1919
use std::cmp::Ordering;
2020
use std::fs::File;
21-
use std::ptr::null_mut;
2221

2322
/* Local variables */
2423
static mut thor_game_count: i32 = 0;
@@ -585,7 +584,7 @@ pub unsafe fn sort_thor_games(count: i32) {
585584
}
586585
let sord_order = &thor_sort_order[0..thor_sort_criteria_count as usize];
587586
thor_search.match_list.sort_by(|g1, g2| {
588-
match unsafe { thor_compare(&**g1, &**g2, sord_order, &players, &tournaments) } {
587+
match unsafe { thor_compare(g1.unwrap(), g2.unwrap(), sord_order, &players, &tournaments) } {
589588
i32::MIN..=-1_i32 => Ordering::Less,
590589
0 => Ordering::Equal,
591590
1_i32..=i32::MAX => Ordering::Greater,
@@ -605,7 +604,7 @@ pub unsafe fn print_thor_matches(mut stream: &mut impl Write, max_games: i32) {
605604
if i == 0 {
606605
stream.write(b"\n");
607606
}
608-
print_game(&mut stream, &**thor_search.match_list.offset(i as isize), 0, &tournaments, &players);
607+
print_game(&mut stream, thor_search.match_list.offset(i as isize).unwrap(), 0, &tournaments, &players);
609608
i += 1
610609
};
611610
}
@@ -1353,7 +1352,7 @@ unsafe fn get_thor_game(index: i32) -> GameInfoType {
13531352
info.black_corrected_score = 32
13541353
} else {
13551354
/* Copy name fields etc */
1356-
let game = *thor_search.match_list.offset(index as isize);
1355+
let game = thor_search.match_list.offset(index as isize).unwrap();
13571356
info.black_name = players.get_player_name((*game).black_no as i32);
13581357
info.white_name = players.get_player_name((*game).white_no as i32);
13591358
info.tournament = tournaments.tournament_name((*game).tournament_no as i32);
@@ -1530,7 +1529,7 @@ impl ThorBoard {
15301529
Play the MAX_MOVES first moves of GAME and update THOR_BOARD
15311530
and THOR_SIDE_TO_MOVE to represent the position after those moves.
15321531
*/
1533-
fn play_through_game(&mut self, game: &mut GameType, max_moves: i32) -> i32 {
1532+
fn play_through_game(&mut self, game: &GameType, max_moves: i32) -> i32 {
15341533
let mut move_0: i32 = 0;
15351534
let mut flipped: i32 = 0;
15361535
clear_thor_board(&mut self.board);
@@ -1653,10 +1652,10 @@ fn prepare_game(mut game: &mut GameType, thor_board: &mut ThorBoard, tree: &mut
16531652
}
16541653
(*game).opening = opening;
16551654
/* Initialize the shape state */
1656-
(*game).shape_lo = 3 << 27;
1657-
(*game).shape_hi = 3 << 3;
1658-
(*game).shape_state_hi = 0;
1659-
(*game).shape_state_lo = 0;
1655+
(*game).shape_lo.set(3 << 27);
1656+
(*game).shape_hi.set(3 << 3);
1657+
(*game).shape_state_hi.set(0);
1658+
(*game).shape_state_lo.set(0);
16601659
/* Store the corner descriptor */
16611660
(*game).corner_descriptor = corner_descriptor;
16621661
}
@@ -1919,19 +1918,18 @@ pub unsafe fn init_thor_database(random: &mut MyRandom) {
19191918
*/
19201919

19211920
unsafe fn get_thor_game_moves(index: i32, move_count: &mut i32, moves: &mut [i32]) {
1922-
let mut game = 0 as *mut GameType;
19231921
if index < 0 || index >= thor_search.match_count {
19241922
/* Bad index, so fill with empty values */
19251923
*move_count = 0
19261924
} else {
1927-
game = *thor_search.match_list.offset(index as isize);
1925+
let game = thor_search.match_list.offset(index as isize).unwrap();
19281926
*move_count = (*game).move_count as i32;
1929-
match (*game).matching_symmetry as i32 {
1927+
match (*game).matching_symmetry.get() as i32 {
19301928
0 | 2 | 5 | 7 => {
19311929
/* Symmetries that preserve the initial position. */
19321930
let mut i = 0;
19331931
while i < (*game).move_count as i32 {
1934-
*moves.offset(i as isize) = *symmetry_map[(*game).matching_symmetry as usize].offset(abs((*game).moves[i as usize] as i32) as isize);
1932+
*moves.offset(i as isize) = *symmetry_map[(*game).matching_symmetry.get() as usize].offset(abs((*game).moves[i as usize] as i32) as isize);
19351933
i += 1
19361934
}
19371935
}
@@ -1956,12 +1954,12 @@ pub unsafe fn get_thor_game_move(index: i32, move_number: i32) -> i32 {
19561954
if index < 0 || index >= thor_search.match_count {
19571955
-1
19581956
} else {
1959-
let game = *thor_search.match_list.offset(index as isize);
1957+
let game = thor_search.match_list.offset(index as isize).unwrap();
19601958
if move_number < 0 ||
19611959
move_number >= (*game).move_count as i32 {
19621960
-1
19631961
} else {
1964-
*symmetry_map[(*game).matching_symmetry as usize].offset(abs((*game).moves[move_number as usize] as i32) as isize)
1962+
*symmetry_map[(*game).matching_symmetry.get() as usize].offset(abs((*game).moves[move_number as usize] as i32) as isize)
19651963
}
19661964
}
19671965
}
@@ -1972,7 +1970,7 @@ pub unsafe fn get_thor_game_move(index: i32, move_number: i32) -> i32 {
19721970
SIDE_TO_MOVE being the player to move, matches the hash codes
19731971
IN_HASH1 and IN_HASH2, otherwise FALSE.
19741972
*/
1975-
fn position_match(mut game: &mut GameType,
1973+
fn position_match(mut game: &GameType,
19761974
thor_board: &mut ThorBoard,
19771975
thor_hash_: &mut ThorHash,
19781976
tree: &mut ThorOpeningTree,
@@ -2010,58 +2008,58 @@ fn position_match(mut game: &mut GameType,
20102008
/* Check if the opening information suffices to
20112009
determine if the position matches or not. */
20122010
if (tree[game.opening]).current_match == 1 {
2013-
(*game).matching_symmetry = (tree[game.opening]).matching_symmetry as i16;
2011+
(*game).matching_symmetry.set((tree[game.opening]).matching_symmetry as i16);
20142012
return 1
20152013
} else {
20162014
if (tree[game.opening]).current_match == 2 {
20172015
return 0
20182016
}
20192017
}
20202018
/* Check if the lower 32 bits of the shape state coincide */
2021-
if ((*game).shape_state_lo as i32) < move_count {
2022-
i = (*game).shape_state_lo as i32;
2019+
if ((*game).shape_state_lo.get() as i32) < move_count {
2020+
i = (*game).shape_state_lo.get() as i32;
20232021
while i < move_count {
2024-
(*game).shape_lo |= move_mask_lo[abs((*game).moves[i as usize] as i32) as usize];
2022+
(*game).shape_lo.set((*game).shape_lo.get() | move_mask_lo[abs((*game).moves[i as usize] as i32) as usize]);
20252023
i += 1
20262024
}
2027-
(*game).shape_state_lo = move_count as i16
2028-
} else if (*game).shape_state_lo as i32 > move_count {
2029-
i = (*game).shape_state_lo as i32 - 1;
2025+
(*game).shape_state_lo.set(move_count as i16)
2026+
} else if (*game).shape_state_lo.get() as i32 > move_count {
2027+
i = (*game).shape_state_lo.get() as i32 - 1;
20302028
while i >= move_count {
2031-
(*game).shape_lo &= !move_mask_lo[abs((*game).moves[i as usize] as i32) as usize];
2029+
(*game).shape_lo.set((*game).shape_lo.get() & !move_mask_lo[abs((*game).moves[i as usize] as i32) as usize]);
20322030
i -= 1
20332031
}
2034-
(*game).shape_state_lo = move_count as i16
2032+
(*game).shape_state_lo.set(move_count as i16);
20352033
}
20362034
shape_match = 0;
20372035
i = 0;
20382036
while i < 8 {
2039-
shape_match |= ((*game).shape_lo == *shape_lo.offset(i as isize)) as i32;
2037+
shape_match |= ((*game).shape_lo.get() == *shape_lo.offset(i as isize)) as i32;
20402038
i += 1
20412039
}
20422040
if shape_match == 0 {
20432041
return 0
20442042
}
20452043
/* Check if the upper 32 bits of the shape state coincide */
2046-
if ((*game).shape_state_hi as i32) < move_count {
2047-
i = (*game).shape_state_hi as i32;
2044+
if ((*game).shape_state_hi.get() as i32) < move_count {
2045+
i = (*game).shape_state_hi.get() as i32;
20482046
while i < move_count {
2049-
(*game).shape_hi |= move_mask_hi[abs((*game).moves[i as usize] as i32) as usize];
2047+
(*game).shape_hi.set((*game).shape_hi.get() | move_mask_hi[abs((*game).moves[i as usize] as i32) as usize]);
20502048
i += 1
20512049
}
2052-
(*game).shape_state_hi = move_count as i16
2053-
} else if (*game).shape_state_hi as i32 > move_count {
2054-
i = (*game).shape_state_hi as i32 - 1;
2050+
(*game).shape_state_hi.set(move_count as i16)
2051+
} else if (*game).shape_state_hi.get() as i32 > move_count {
2052+
i = (*game).shape_state_hi.get() as i32 - 1;
20552053
while i >= move_count {
2056-
(*game).shape_hi &= !move_mask_hi[abs((*game).moves[i as usize] as i32) as usize];
2054+
(*game).shape_hi.set((*game).shape_hi.get() & !move_mask_hi[abs((*game).moves[i as usize] as i32) as usize]);
20572055
i -= 1
20582056
}
2059-
(*game).shape_state_hi = move_count as i16
2057+
(*game).shape_state_hi.set(move_count as i16)
20602058
}
20612059
shape_match = 0;
20622060
i = 0;
20632061
while i < 8 {
2064-
shape_match |= ((*game).shape_hi == *shape_hi.offset(i as isize)) as i32;
2062+
shape_match |= ((*game).shape_hi.get() == *shape_hi.offset(i as isize)) as i32;
20652063
i += 1
20662064
}
20672065
if shape_match == 0 {
@@ -2084,7 +2082,7 @@ fn position_match(mut game: &mut GameType,
20842082
i = 0;
20852083
while i < 8 {
20862084
if primary_hit_mask & secondary_hit_mask & (1) << i != 0 {
2087-
(*game).matching_symmetry = i as i16;
2085+
(*game).matching_symmetry.set(i as i16);
20882086
return 1
20892087
}
20902088
i += 1
@@ -2274,7 +2272,6 @@ pub unsafe fn database_search(in_board: &[i32], side_to_move: i32) {
22742272
let mut corner_mask: u32 = 0;
22752273
let mut shape_lo: [u32; 8] = [0; 8];
22762274
let mut shape_hi: [u32; 8] = [0; 8];
2277-
let mut game;
22782275
/* We need a player and a tournament database. */
22792276
if players.count() == 0 ||
22802277
tournaments.count() == 0 {
@@ -2284,10 +2281,10 @@ pub unsafe fn database_search(in_board: &[i32], side_to_move: i32) {
22842281
/* Make sure there's memory allocated if all positions
22852282
in all databases match the position */
22862283
if thor_search.allocation == 0 {
2287-
thor_search.match_list = vec![null_mut(); thor_game_count as usize];
2284+
thor_search.match_list = vec![Default::default(); thor_game_count as usize];
22882285
thor_search.allocation = thor_game_count
22892286
} else if thor_search.allocation < thor_game_count {
2290-
thor_search.match_list = vec![null_mut(); thor_game_count as usize];
2287+
thor_search.match_list = vec![Default::default(); thor_game_count as usize];
22912288
thor_search.allocation = thor_game_count
22922289
}
22932290
/* If necessary, filter all games in the database */
@@ -2297,22 +2294,22 @@ pub unsafe fn database_search(in_board: &[i32], side_to_move: i32) {
22972294
}
22982295
/* If necessary, sort all games in the database */
22992296
if thor_games_sorted == 0 {
2300-
let mut current_db_ = &mut database_head;
2297+
let mut current_db_ = &database_head;
23012298
i = 0;
23022299
while let Some(current_db) = current_db_ {
23032300
j = 0;
23042301
while j < (*current_db).count {
23052302
let ref mut fresh5 = *thor_search.match_list.offset(i as isize);
2306-
*fresh5 = &mut *(*current_db).games.offset(j as isize) as *mut GameType;
2303+
*fresh5 = Some((*current_db).games.as_slice().offset(j as isize));
23072304
i += 1;
23082305
j += 1
23092306
}
2310-
current_db_ = &mut (*current_db).next
2307+
current_db_ = &(*current_db).next
23112308
}
23122309
sort_thor_games(thor_game_count);
23132310
j = 0;
23142311
while j < thor_game_count {
2315-
(**thor_search.match_list.offset(j as isize)).sort_order = j;
2312+
(thor_search.match_list.offset(j as isize)).unwrap().sort_order.set(j);
23162313
j += 1
23172314
}
23182315
thor_games_sorted = 1
@@ -2421,7 +2418,7 @@ pub unsafe fn database_search(in_board: &[i32], side_to_move: i32) {
24212418
i = 0;
24222419
while i < thor_game_count {
24232420
let ref mut fresh6 = *thor_search.match_list.offset(i as isize);
2424-
*fresh6 = 0 as *mut GameType;
2421+
*fresh6 = None;//0 as *mut GameType;
24252422
i += 1
24262423
}
24272424
i = 0;
@@ -2435,17 +2432,17 @@ pub unsafe fn database_search(in_board: &[i32], side_to_move: i32) {
24352432
thor_search.next_move_score[i as usize] = 0.0f64;
24362433
i += 1
24372434
}
2438-
let mut current_db_ = &mut database_head;
2435+
let mut current_db_ = & database_head;
24392436
while let Some(current_db) = current_db_ {
24402437
i = 0;
24412438
while i < (*current_db).count {
2442-
game = &mut *(*current_db).games.offset(i as isize);
2439+
let game = (*current_db).games.as_slice().offset(i as isize);
24432440
if (*game).passes_filter != 0 {
24442441
if disc_count[0] == (*game).black_disc_count[move_count as usize] as i32 {
24452442
if position_match(game, &mut board, &mut thor_hash, &mut thor_opening_tree, move_count, side_to_move, &mut shape_lo, &mut shape_hi, corner_mask, target_hash1, target_hash2) != 0 {
2446-
let ref mut fresh7 = *thor_search.match_list.offset((*game).sort_order as isize);
2447-
*fresh7 = game;
2448-
symmetry = (*game).matching_symmetry as i32;
2443+
let ref mut fresh7 = *thor_search.match_list.offset(game.sort_order.get() as _);
2444+
*fresh7 = Some(game);
2445+
symmetry = (game).matching_symmetry.get() as i32;
24492446
if move_count < (*game).move_count as i32 {
24502447
next_move = *symmetry_map[symmetry as usize].offset(
24512448
abs((*game).moves[move_count as usize] as i32) as isize
@@ -2468,7 +2465,7 @@ pub unsafe fn database_search(in_board: &[i32], side_to_move: i32) {
24682465
}
24692466
i += 1
24702467
}
2471-
current_db_ = &mut (*current_db).next
2468+
current_db_ = &(*current_db).next
24722469
}
24732470
/* Remove the NULLs from the list of matching games if there are any.
24742471
This gives a sorted list. */
@@ -2477,7 +2474,7 @@ pub unsafe fn database_search(in_board: &[i32], side_to_move: i32) {
24772474
i = 0;
24782475
j = 0;
24792476
while i < thor_search.match_count {
2480-
if !(*thor_search.match_list.offset(j as isize)).is_null() {
2477+
if !(*thor_search.match_list.offset(j as isize)).is_none() {
24812478
let ref mut fresh8 = *thor_search.match_list.offset(i as isize);
24822479
*fresh8 = *thor_search.match_list.offset(j as isize);
24832480
i += 1

crates/thordb-types/thordb-types.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::cell::Cell;
12
use std::ops::{Index, IndexMut};
23

34
#[derive(Copy, Clone)]
@@ -95,7 +96,7 @@ pub struct DatabaseType {
9596
pub count: i32,
9697
pub next: Option<Box<DatabaseType>>,
9798
}
98-
#[derive(Copy, Clone)]
99+
#[derive(Clone)]
99100
#[repr(C)]
100101
pub struct GameType {
101102
pub tournament_no: i16,
@@ -111,13 +112,13 @@ pub struct GameType {
111112

112113
// replacement for `database` field, because we only need a year from it
113114
pub origin_year: i32,
114-
pub shape_hi: u32,
115-
pub shape_lo: u32,
116-
pub shape_state_hi: i16,
117-
pub shape_state_lo: i16,
115+
pub shape_hi: Cell<u32>,
116+
pub shape_lo: Cell<u32>,
117+
pub shape_state_hi: Cell<i16>,
118+
pub shape_state_lo: Cell<i16>,
118119
pub corner_descriptor: u32,
119-
pub sort_order: i32,
120-
pub matching_symmetry: i16,
120+
pub sort_order: Cell<i32>,
121+
pub matching_symmetry: Cell<i16>,
121122
pub passes_filter: i16,
122123
}
123124

@@ -134,13 +135,13 @@ impl GameType {
134135
black_disc_count: [0; 61],
135136
opening: OpeningNodeRef::root(),
136137
origin_year: 0,
137-
shape_hi: 0,
138-
shape_lo: 0,
139-
shape_state_hi: 0,
140-
shape_state_lo: 0,
138+
shape_hi: Cell::new(0),
139+
shape_lo: Cell::new(0),
140+
shape_state_hi: Cell::new(0),
141+
shape_state_lo: Cell::new(0),
141142
corner_descriptor: 0,
142-
sort_order: 0,
143-
matching_symmetry: 0,
143+
sort_order: Cell::new(0),
144+
matching_symmetry: Cell::new(0),
144145
passes_filter: 0,
145146
}
146147
}
@@ -312,7 +313,7 @@ pub struct SearchResultType {
312313
pub median_black_score: i32,
313314
pub allocation: i32,
314315
pub next_move_frequency: [i32; 100],
315-
pub match_list: Vec<*mut GameType>,
316+
pub match_list: Vec<Option<&'static GameType>>,
316317
}
317318
#[derive(Copy, Clone)]
318319
#[repr(C)]
@@ -383,7 +384,7 @@ impl SearchResultType {
383384
/* Bad index */
384385
return -1
385386
} else {
386-
return (*self.match_list[index as usize]).move_count as i32
387+
return (self.match_list[index as usize]).unwrap().move_count as i32
387388
};
388389
}
389390
}

0 commit comments

Comments
 (0)