public object Remove(string name) { int hash = name.GetHashCode(); Cell[] cellsLocalRef = cells; if(count != 0) { int tableSize = cells.Length; int cellIndex = GetCellIndex(tableSize, hash); Cell prev = cellsLocalRef[cellIndex]; Cell cell = prev; while(cell != null) { if(cell.name == name || name.Equals(cell.name)) { break; } prev = cell; cell = cell.next; } if(cell != null) { count--; // remove slot from hash table if(prev == cell) { cellsLocalRef[cellIndex] = cell.next; } else { prev.next = cell.next; } if(firstAdded == cell) { firstAdded = cell.orderedNext; if(lastAdded == cell) { lastAdded = null; } } else { Cell p2 = firstAdded; while(p2.orderedNext != cell) { p2 = p2.orderedNext; } if(p2 != null) { p2.orderedNext = cell.orderedNext; } if(lastAdded == cell) { lastAdded = p2; } } return cell.value; } } return null; }
private static void CopyTable(Cell[] cells, Cell[] newCells, int count) { int tableSize = newCells.Length; int i = cells.Length; for (;;) { --i; Cell cell = cells[i]; while(cell != null) { int insertPos = GetCellIndex(tableSize, cell.hash); Cell next = cell.next; AddKnownAbsentCell(newCells, cell, insertPos); cell.next = null; cell = next; if(--count == 0) return; } } }
private Cell CreateCell(string name, int hash, bool query) { Cell[] cellsLocalRef = cells; int insertPos; if(count == 0) { cellsLocalRef = new Cell[INITIAL_CELL_SIZE]; cells = cellsLocalRef; insertPos = GetCellIndex(cellsLocalRef.Length, hash); } else { int tableSize = cellsLocalRef.Length; insertPos = GetCellIndex(tableSize, hash); Cell prev = cellsLocalRef[insertPos]; Cell cell = prev; while(cell != null) { if(cell.name == name || name.Equals(cell.name)) { break; } prev = cell; cell = cell.next; } if(cell != null) { return cell; } else { if(4 * (count + 1) > 3 * cellsLocalRef.Length) { cellsLocalRef = new Cell[cellsLocalRef.Length * 2]; CopyTable(cells, cellsLocalRef, count); cells = cellsLocalRef; insertPos = GetCellIndex(cellsLocalRef.Length, hash); } } } Cell newCell = new Cell(name, hash); ++count; if(lastAdded != null) lastAdded.orderedNext = newCell; if(firstAdded == null) firstAdded = newCell; lastAdded = newCell; AddKnownAbsentCell(cellsLocalRef, newCell, insertPos); return newCell; }
private static void AddKnownAbsentCell(Cell[] cells, Cell cell, int insertPos) { if(cells[insertPos] == null) { cells[insertPos] = cell; } else { Cell prev = cells[insertPos]; while(prev.next != null) { prev = prev.next; } prev.next = cell; } }